数据表

时间:2016-03-01 15:04:51

标签: r algorithm find-occurrences

(前同步码) 我不知道这是不是正确的地方...我实际上有一个问题解决/优化问题的计数表。所以,如果不是。非常抱歉,应该受到贬低。

这是数据框

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 
}

2 个答案:

答案 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向量。