列聚合

时间:2016-03-05 11:44:27

标签: r

我有一个n列和r行的数据框。我想确定哪个列与列1最相关,然后聚合这两列。聚合列将被视为新列1.然后,我从集合中删除最相关的列。因此,日期的大小减少了一列。然后我重复这个过程,直到数据框result有n列,第二列是两列的聚合,第三列是三列的聚合,等等。因此,我想知道是否有一个有效或更快的方式来达到我想要的结果。我尝试过各种各样的东西,但到目前为止还没有成功。有什么建议吗?

n <- 5
r <- 6


> df
    X1   X2   X3   X4   X5
1 0.32 0.88 0.12 0.91 0.18
2 0.52 0.61 0.44 0.19 0.65
3 0.84 0.71 0.50 0.67 0.36
4 0.12 0.30 0.72 0.40 0.05
5 0.40 0.62 0.48 0.39 0.95
6 0.55 0.28 0.33 0.81 0.60

result应该是这样的:

> result
    X1   X2   X3   X4   X5
1 0.32 0.50 1.38 2.29 2.41
2 0.52 1.17 1.78 1.97 2.41
3 0.84 1.20 1.91 2.58 3.08
4 0.12 0.17 0.47 0.87 1.59
5 0.40 1.35 1.97 2.36 2.84
6 0.55 1.15 1.43 2.24 2.57

2 个答案:

答案 0 :(得分:2)

我认为大部分的缓慢和最终崩溃来自循环期间的内存开销而不是来自相关性(虽然这可以像@coffeeinjunky所说的那样得到改善)。这很可能是由于在R中修改data.frames的方式的结果。考虑切换到data.tables并利用它们的&#34;通过引用分配&#34;范例。例如,下面是您的代码翻译成data.table语法。您可以计算两个循环的时间,比较性能并评论结果。欢呼声。

n <- 5L
r <- 6L

result <- setDT(data.frame(matrix(NA,nrow=r,ncol=n)))
temp <- copy(df) # Create a temporary data frame in which I calculate the correlations
set(result, j=1L, value=temp[[1]]) # The first column is the same

for (icol in as.integer(2:n)) {
  mch <- match(c(max(cor(temp)[-1,1])),cor(temp)[,1]) # Determine which are correlated most
  set(x=result, i=NULL, j=as.integer(icol), value=(temp[[1]] + temp[[mch]]))# Aggregate and place result in results datatable
  set(x=temp, i=NULL, j=1L, value=result[[icol]])# Set result as new 1st column
  set(x=temp, i=NULL, j=as.integer(mch), value=NULL) # Remove column
}

答案 1 :(得分:0)

尝试

for (i in 2:n) {
  maxcor <- names(which.max(sapply(temp[,-1, drop=F], function(x) cor(temp[, 1], x) )))
  result[,i] <- temp[,1] + temp[,maxcor] 
  temp[,1] <- result[,i] # Set result as new 1st column
  temp[,maxcor] <- NULL # Remove column
}

错误是由于在最后一次迭代中,子集temp产生单个向量,标准R行为是在这种情况下将类从数据帧减少到向量,这导致sapply通过仅在第一个元素上等。

还有一条评论:目前,您使用的是最正相关,而不是最强相关,也可能是负相关。确保这是你想要的。

在评论中添加您的问题:请注意,可以通过避免重复计算来改进旧代码。例如,

   mch <- match(c(max(cor(temp)[-1,1])),cor(temp)[,1])

包含命令cor(temp)两次。这意味着每次相关计算两次。用

替换它
  cortemp <- cor(temp)
  mch <- match(c(max(cortemp[-1,1])),cortemp[,1])

应该将初始代码行的计算负担减半。