【问题标题】:R for loop wise : Rowwise sum on conditions : Performance issueR for loop wise : Rowwise sum on conditions : 性能问题
【发布时间】:2021-09-22 12:28:39
【问题描述】:

我有一个数据库,我在其中运行代码来更改单元格的值——基于先前单元格的总和以及同一行中后续单元格的总和。

for (i in 1:row1) 
  
{      
  for(j in 3:col-1) 
  {       # for-loop over columns
    
      if (as.numeric(rowSums(e[i,2:j])) == 0 ) 
      {
        
        e1[i,j] <- 0
        
      }
      else if (as.numeric(rowSums(e[i,2:j])) > 0 &&  e[i,j] == 0 && as.numeric(rowSums(e[i,j:col])) > 0 ) 
      {
        e1[i,j] <- 1
      }
      
      else if (as.numeric(rowSums(e[i,2:j])) > 0 &&  e[i,j] == 1 && as.numeric(rowSums(e[i,j:col])) > 0 )    
      {
        e1[i,j] <- 0
        
      }        
      
    }
    
} 

运行时间非常长。感谢任何提高速度的建议。附加信息:正在将新值复制到数据框中。

谢谢, 桑迪

编辑 2:

样本数据:

structure(list(`Sr no` = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
12, 13, 14, 15, 16, 17, 18, 19), `2018-01` = c(0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2018-02` = c(0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2018-03` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2018-04` = c(0, 
0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2018-05` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0), `2018-06` = c(0, 
0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0), `2018-07` = c(0, 
0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0), `2018-08` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1), `2018-09` = c(0, 
0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0), `2018-10` = c(1, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1), `2018-11` = c(0, 
1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1), `2018-12` = c(1, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2019-01` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), `2019-02` = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)), row.names = c(NA, 
-19L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • for 循环和嵌套 if 通常不是最快的选择。但是由于您没有提供ee1colrow1 的任何样本数据,我怀疑任何人都可以提供可靠的答案..
  • 感谢您的回复。我根据您的建议添加了示例数据库的图像和其他信息
  • 提供的数据不是真实的样本数据......这是数据的图片......我无法将其读入R。请创建一个最小样本集(不必是生产数据) , 并使用dput(e) 发布,或者如果太滞后,dput(head(e))。可以将此输出复制粘贴到您的问题中(在代码块内),然后直接粘贴到 R 中。对所需的输出 e1 执行相同操作。有关如何创建最小样本集的更多信息:stackoverflow.com/a/5963610/6356278
  • 您对共享数据的预期输出是什么?
  • @Ronak Shah 1 代表客户的“服务”。 0 代表“关闭服务”。我想强调任何两个后续“服务”之间的停顿。如果他们在下个月不是“1”,则客户离开

标签: r performance runtime rowsum


【解决方案1】:

我认为您可以使用matrix 逻辑来做到这一点。取决于你是否有足够的内存。

# creating fake data
# nc <- 300 # number of columns
nc <- 10 # for testing
nn <- 1e6 # rows
e <- sapply(1:nc, function(x) sample.int(2, nn, replace = T) - 1L) 
e <- as.data.frame(e)

row1 <- nrow(e)
colc <- ncol(e)
# note that:
3:colc-1
# isnt equal with:
3:(colc-1)

s <- 3:(colc-1) # I assume you meant this
e1 <- matrix(nrow = row1, ncol = length(s)) # empty resulting matrix
s1 <- sapply(s, function(j) rowSums(e[, 2:j])) # sum for each relevant i,j
s2 <- sapply(s, function(j) rowSums(e[, j:colc])) # sum for each relevant i,j

e2 <- as.matrix(e[, s]) # taking relevant columns of e

e1[s1 == 0] <- 0
e1[s1 > 0 &  e2 == 0 & s2 > 0] <- 1
e1[s1 > 0 &  e2 == 1 & s2 > 0] <- 0

【讨论】:

  • 谢谢,时间减少了一半。
  • @Sandy 你也可以从matrixStats 包中查看rowSums2。它可以带来一些改进。
  • 感谢您的建议。我会仔细看看的。如果遇到任何问题,我会提出一个新的问题。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多