(前同步码) 我不知道这是不是正确的地方...我实际上有一个问题解决/优化问题的计数表。所以,如果不是。非常抱歉,应该受到贬低。
这是数据框
dat <- data.frame(id=letters[1:5],matrix(c(0,0,1,0,0, 0,1,0,1,1, 0,0,2,1,0, 1,0,2,1,1, 0,0,2,0,0, 0,1,2,1,0),5,6))
#
# id X1 X2 X3 X4 X5 X6
# 1 a 0 0 0 1 0 0
# 2 b 0 1 0 0 0 1
# 3 c 1 0 2 2 2 2
# 4 d 0 1 1 1 0 1
# 5 e 0 1 0 1 0 0
我想计算每一行,我们达到1的次数以及从1开始的次数为0.所以最终的结果应该是
# id N1 N0
# a 1 1
# b 2 1
# c 1 1
# d 2 1
# e 2 2
我实际上找到了一个算法,但它有更多的C / FORTRAN风格(在下面这里),我不能相信它不是一个更精简,更优雅的方式来获得这个。谢谢任何帮助或提示很多。
nr <- nrow(dat)
nc <- ncol(dat)
rownames(dat) <- seq(1,nr,1)
colnames(dat) <- seq(1,nc,1)
dat$N1 <- NULL
dat$N2 <- NULL
for (i in 1:nr) {
n1 <- 0
n0 <- 0
j <- 2
while (!(j>nc)) {
k <- j
if (dat[i,k] == 1) {
n1 <- n1 + 1
k <- j + 1
while (!(k>nc)) {
if (dat[i,k] == 0) {
n0 <- n0 + 1
break
}
k <- k + 1
}
}
j <- k
j <- j + 1
}
dat$N1[i] <- n1
dat$N0[i] <- n0
}
答案 0 :(得分:2)
不确定我是否完全得到它,但您可以尝试:
cbind(dat["id"],N0=rowSums(dat[,3:7]==1 & dat[,2:6]!=1)+(dat[,2]==1),
N1=rowSums(dat[,3:7]==0 & dat[,2:6]==1))
# id N0 N1
#1 a 1 1
#2 b 2 1
#3 c 1 1
#4 d 2 1
#5 e 2 2
答案 1 :(得分:1)
以其他方式,使用data.table语法包含的rle
:
library(data.table)
setDT(dat)
melt(dat, id="id")[, with(rle(value), list(
n1 = sum(values==1),
n1to0 = sum("10" == do.call(paste0, shift(values, 1:0, fill=0)))
)), by=id]
# id n1 n1to0
# 1: a 1 1
# 2: b 2 1
# 3: c 1 1
# 4: d 2 1
# 5: e 2 2
注释
shift
的n=1:0
返回滞后向量(滞后为1)和向量本身(滞后为0)。melt
创建value
列;并且rle
包含values
向量。