数据中的特殊出现计数 table

Special occurrency counting in data table

(序言) 我不知道这是否是正确的地方...我实际上有一个 solving/optimization 的问题,关于 table 的计数。所以如果不是。非常抱歉,值得负分。

这是数据框

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 风格(如下所示),我不敢相信在 R 中没有更简单、更优雅的方法。非常感谢您的帮助或暗示。

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 
}

不确定我是否完全理解,但你可以试试:

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

这是另一种方法,使用 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

注释。

  • shiftn=1:0 returns 滞后向量(滞后 1)和向量本身(滞后 0)。
  • melt 创建一个 value 列; rle 包含一个 values 向量。