我试图将包含状态的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 | +----+--------+------+---+---+---+
感谢任何评论或提示。
答案 0 :(得分:2)
第一行创建一个n×3矩阵xna
,其列对应于a
,b
和c
,其元素是{{的对应值1}}如果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, ])
更新缩短代码。
答案 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