更好的方法在df上进行条件求和而不是for循环?

时间:2015-01-06 04:28:02

标签: r dataframe conditional vectorization

我正在使用for循环对数据帧进行求和。我知道,在R中循环并不是一个好主意,并且使用sapply或aggregate这是一个更好的方法,但我不知道如何在我的情况下使用它。

我想以迭代的方式基于两列的条件对一列进行求和。

以下是我想要更好地理解的内容:

sample  <- data.frame( ID = c("bli","bla","blou","qhq","bidi","bada","bodo"),
        A = c(1,0,1,1,0,1,1) , 
        B = c(0,1,1,0,0,1,0) ,
        C = c(0,1,1,0,0,1,1) 

                  )


 g  <-  NULL 
bli  <- 1:length(sample)
for (j in 2:length(sample)) {
  a <- sum(subset(sample,sample[,c(j) ] ==1 , c(j)))
  for (i in 2:length(sample)) 
    if (bli[j] != bli[i]) {
    b  <- sum(subset(sample,sample[,c(j)] ==1 & sample[,c(i) ] ==1 , c(i)))
    c <- names(sample[j])
    d <- names(sample[i])
    e  <- cbind(c,d,a,b)
    f  <- data.frame(e)
    g <-  rbind(g,f) } 
  else {
    NULL
}

  }
g

由于

1 个答案:

答案 0 :(得分:2)

您可以尝试expand.grid(@thelatemail建议)。以下代码摘要如下:

  1. 创建列名称(即“nm1”)的“索引”,我们需要所有组合
  2. 在自身expand.grid上尝试“{1}}”nm1“。语法expand.grid(nm1, nm1)有点笼统,因此您可以通过在list(nm1)中指定times来创建多方式组合。
  3. 删除相同的行(“indx1”)
  4. 使用rep循环遍历“indx1”行并使用基于循环中的行索引对“样本”数据集进行子集。
  5. 根据子集数据集(sapply中的元素是否为“1”,基于“indx1”和sum的第一列基于子集执行sum
  6. sum(x2[,1]&x2[,2])“indx1”与cbind的转置(t)并重命名输出数据集的列。

    sapply
  7. 甚至不使用nm1 <- names(sample)[-1] indx <- expand.grid(rep(list(nm1),2),stringsAsFactors=FALSE) indx <- indx[,2:1] indx1 <- indx[indx[,1]!=indx[,2],] row.names(indx1) <- NULL res <- cbind(indx1,t(sapply(seq_len(nrow(indx1)), function(i) { x1 <- unlist(indx1[i,]) x2 <- sample[,x1] c(sum(x2[,1]), sum(x2[,1]&x2[,2])) })) ) names(res) <- names(g) res # c d a b #1 A B 5 2 #2 A C 5 3 #3 B A 3 2 #4 B C 3 3 #5 C A 4 3 #6 C B 4 3 (会更快),在子集数据集“i1”,“i2”上使用sapply

    colSums