R 数据帧中连续零的计数
下面是我的数据框架。它有行名和列名R 数据帧中连续零的计数,r,dataframe,R,Dataframe,下面是我的数据框架。它有行名和列名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 我想基于连续零(从最后一列开始,跨每行的列)派生一个列测试。下面是一个示例。对于第一行,有8个连续零,因此测试行中的值应该是8。对于第二行,结果应该是1,因为只有一个零。(我想从15开始,回到零开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0
row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0
我想基于连续零(从最后一列开始,跨每行的列)派生一个列测试。下面是一个示例。对于第一行,有8个连续零,因此测试行中的值应该是8。对于第二行,结果应该是1,因为只有一个零。(我想从15开始,回到零开始的地方)。< /P>
实现这一点的最佳方法是什么?使用
rle的解决方案
:
getConsecZeroRle <- function(x) {
foo <- rle(x)
foo$lengths[tail(which(foo$values), 1)]
}
result <- apply(df[, -1] == 0, 1, function(x) getConsecZeroRle(x))
df$test <- as.numeric(result)
df$test[is.na(df$test)] <- 0
说明:
提取每行中最后一个
FALSE
值,并使用rle
将其前面的所有内容都转换为FALSE
(x[1:tail(which(!x),1)]解决方案:
getConsecZeroRle <- function(x) {
foo <- rle(x)
foo$lengths[tail(which(foo$values), 1)]
}
result <- apply(df[, -1] == 0, 1, function(x) getConsecZeroRle(x))
df$test <- as.numeric(result)
df$test[is.na(df$test)] <- 0
说明:
提取每行中最后一个FALSE
值,并将其前面的所有内容都设置为FALSE
(x[1:tail(which(!x),1)]您只需找到不等于0
的第一个值的索引(从最后一列开始),然后减去一个:
df$test2 <- apply(df[,ncol(df):1]==0, 1, which.min) - 1
df
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test2
#1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8
#2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1
这背后的想法是使用names
属性跟踪列是否为0
。如果是,则停止计数,否则继续计数。您只需找到不等于0
的第一个值的索引(从最后一列开始),然后减去一个:
df$test2 <- apply(df[,ncol(df):1]==0, 1, which.min) - 1
df
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test2
#1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8
#2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1
这背后的想法是使用names
属性来跟踪列是否为0
。如果是,则停止计数,否则继续计数。c(0,0,0,1,0,0)的结果是什么<代码>?它应该是2。你能解释为什么不是3吗?嗯,谢谢你指出这一点,我想从D5,D4和回去。基本上,因为多少天的值是零。删除我的答案作为例子中的问题不断改变什么结果为<代码> C(0, 0, 0,1, 0, 0)。<代码>?它应该是2。你能解释为什么不是3吗?嗯,谢谢你指出这一点,我想从D5,D4和回去。基本上,因为多少天的值是零。删除我的答案作为例子中的问题不断改变这里是我的数据框只有一行(它有一些行名和姓氏)。0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0。
df$test2 <- apply(df[,ncol(df):1]==0, 1, which.min) - 1
df
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test2
#1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8
#2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1
iniCol <- setNames(df[,ncol(df)] == 0, as.numeric(df[,ncol(df)] == 0))
df$test2 <- Reduce(function(ini, add) {temp <- ifelse(pmin(as.numeric(names(ini)), add==0) == 0, ini, rowSums(cbind(ini, add == 0)))
ini <- setNames(temp, pmin(as.numeric(names(ini)), add==0))},
df[,(ncol(df)-1):1],
ini = iniCol)