将列表转换为相同长度的特殊矩阵

时间:2014-10-29 15:58:58

标签: r

我试图将包含状态的ID列表转换为一种长度相同的矩阵。我想知道我需要保持状态开/关直到它发生变化。

有人知道如何从这里开始或指向一个可以尝试应用的方法吗?

输入下方(左侧)和所需输出(右侧)。

+----+--------+------+---+---+---+
| 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 个答案:

答案 0 :(得分:2)

第一行创建一个n×3矩阵xna,其列对应于abc,其元素是{{的对应值1}}如果dat$STATUS等于列名,则ID。然后,我们将NAON转换为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, ])

更新缩短代码。

答案 1 :(得分:0)

我假设您的意思是要按顺序逐步应用状态条件。因此,行4:6将A设为1,因为A在第3行中打开,但尚未关闭。

要做到这一点,你可以这样做。它使用了一个不是'R-ish'的for循环,但它是完成我认为你要求的直接方式

# 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