对一行数据帧中的值求和 - 执行时间

时间:2016-11-11 14:40:55

标签: r dataframe

所以我有2个数据帧,它们都具有相同的结构:

V1  V2  V3  V4  C
0   1   1   0  -1
0   0   1   0  -1
2   0   0   0   1
2   0   0   0   1
1   0   0   0   1
2   0   0   0   1

V1-V4列是整数类型,C列是2级的因子。 数据帧具有不同的大小,第一个具有~50 000行,另一个具有~600 000行。我编写了一个简单的函数,它将行的每个元素除以该行中元素的总和:

SimpleFunction <- function(dataset) {
  progress.bar <- create_progress_bar("text")
  progress.bar$init(nrow(dataset))
  for (i in 1:nrow(dataset)) {
    row.sum <- sum(dataset[i,1:4])
    dataset[i,1] <- dataset[i,1] / row.sum
    dataset[i,2] <- dataset[i,2] / row.sum
    dataset[i,3] <- dataset[i,3] / row.sum
    dataset[i,4] <- dataset[i,4] / row.sum
  progress.bar$step()
  } 
  return(dataset)
}

现在我用“system.time”测试了这个函数执行的次数,对于50000行数据帧,它是~45秒,但是对于600000行的数据帧它需要非常长的时间(大约2分钟为1) %,我用“plyr”包中的这个简单的进度条测量它。现在我的问题是:为什么?唯一改变的是行数,数据帧的结构是相同的。不应该是线性增长,如50000 - 45秒,600000 - 540秒? 我可以简单地划分大数据帧,在每个片段上运行函数然后将它们合并在一起,但我真的不明白为什么会发生这种情况。

2 个答案:

答案 0 :(得分:1)

您不需要为此R使用循环专门进行矢量化计算。所有循环行都会增加处理时间。因此,您可以执行此操作,R将为每行创建行总和:

row.sum <- rowSums(dataset[,1:4])
dataset[,1] <- dataset[,1] / row.sum
dataset[,2] <- dataset[,2] / row.sum
dataset[,3] <- dataset[,3] / row.sum
dataset[,4] <- dataset[,4] / row.sum  

答案 1 :(得分:1)

如果你想要一个行解决方案,

sweep在这里很有用:

> dataset[, 1:4] <- sweep(dataset[,-5], 1, rowSums(dataset[,-5]), FUN="/")
> dataset
  V1  V2  V3 V4  C
1  0 0.5 0.5  0 -1
2  0 0.0 1.0  0 -1
3  1 0.0 0.0  0  1
4  1 0.0 0.0  0  1
5  1 0.0 0.0  0  1
6  1 0.0 0.0  0  1

apply也适用:

dataset[, -5] <- apply(dataset[,-5], 2, function(x) x/rowSums(dataset[,-5]))