2014-10-29 2 views
2

Я пытаюсь преобразовать список идентификаторов, включая состояние, в виде матрицы такой же длины. Я борется с тем, что мне нужно поддерживать статус ON/OFF, пока он не изменится.Преобразование списка в специальную матрицу той же длины

Есть ли у кого-нибудь идея, как начать здесь или указать на метод, который может попытаться применить?

Ниже ввода у меня есть (левая сторона), а также нужный выход (правая сторона).

 
+----+--------+------+---+---+---+ 
| ID | STATUS | - | a | b | c | 
+----+--------+------+---+---+---+ 
| a | ON  | - | 1 | 0 | 0 | 
| a | OFF | - | 0 | 0 | 0 | 
| a | ON  | - | 1 | 0 | 0 | 
| b | ON  | - | 1 | 1 | 0 | 
| b | OFF | - | 1 | 0 | 0 | 
| b | ON  | - | 1 | 1 | 0 | 
| a | OFF | - | 0 | 1 | 0 | 
| c | ON  | - | 0 | 1 | 1 | 
| b | OFF | - | 0 | 0 | 1 | 
| c | OFF | - | 0 | 0 | 0 | 
+----+--------+------+---+---+---+ 

Любые комментарии или подсказки.

ответ

2

первая строка создает матрицу n на 3, xna, столбцы которой соответствуют a, b и c и элементы которой соответствуют значению dat$STATUS, если ID равно имени столбца и NA в противном случае. Затем мы конвертируем ON и OFF в 1 и 0, давая x01. Наконец, мы вставляем фиктивную первую строку нулей, а затем используйте na.locf из зоопарка, чтобы заполнить значения NA, удаляя только что вставленную фиктивную строку.

library(zoo) 

xna <- ifelse(sapply(unique(dat$ID), "==", dat$ID), dat$STATUS, NA) 
x01 <- (xna == "ON") + 0 
data.frame(dat, na.locf(rbind(0, x01))[-1, ]) 

В результате

ID STATUS a b c 
1 a  ON 1 0 0 
2 a OFF 0 0 0 
3 a  ON 1 0 0 
4 b  ON 1 1 0 
5 b OFF 1 0 0 
6 b  ON 1 1 0 
7 a OFF 0 1 0 
8 c  ON 0 1 1 
9 b OFF 0 0 1 
10 c OFF 0 0 0 

Update Сокращенный код.

+0

Большое спасибо, я проверю это предложение с моей стороны и опубликую сообщение здесь. – kukuk1de

+0

Я также проверил с большим набором данных, он работает очень хорошо, а также дает желаемый результат. Кроме того, мне нравится идея использовать эту функцию из пакета zoo вместо цикла. В очередной раз благодарим за помощь! – kukuk1de

0

Я предполагаю, что вы хотите, чтобы вы применяли условия состояния последовательно и постепенно. Следовательно, строки 4: 6 имеют A как 1, потому что A был включен в строке 3 и еще не выключен.

Для этого вы можете это сделать. Он использует цикл, который не является «R-иш», но это простой способ сделать то, что я думаю, что вы просите

# the data 
status <- 
    data.frame(ID=c('a','a','a','b','b','b','a','c','b','c'), 
      STATUS=c('ON','OFF','ON','ON','OFF','ON','OFF','ON','OFF','OFF'), 
      stringsAsFactors=F) 

# unique cols 
unq_cols <- unique(status$ID) 

# set up, empty matrix and default row of 3 'offs' 
out_mat <- NULL 
temp_row <- c(0,0,0) 

# apply the status conditions in order 
for (i in 1:nrow(status)) { 
    col_pos <- grep(status[i, 'ID'], unq_cols) 
    temp_row[col_pos] <- ifelse(status[i, 'STATUS']=='ON', 1, 0) 
    out_mat <- rbind(out_mat, unname(temp_row)) 
} 

# here's your matrix 
out_mat 

выход, который соответствует тому, что у вас есть выше:

 [,1] [,2] [,3] 
[1,]  1 0 0 
[2,]  0 0 0 
[3,]  1 0 0 
[4,]  1 1 0 
[5,]  1 0 0 
[6,]  1 1 0 
[7,]  0 1 0 
[8,]  0 1 1 
[9,]  0 0 1 
[10,] 0 0 0 
+0

Большое спасибо, я также проверю этот подход. – kukuk1de

Смежные вопросы