如何优化for循环以填充数据帧R.

时间:2017-02-09 10:02:48

标签: r for-loop optimization dataframe

我有一个数据框,我在其中计算距离矩阵。

bb=data.frame(Name=paste0('row',1:10),col1=rnorm(10),col2=2*rnorm(10),col3=5*rnorm(10))
dis <- dist(bb[1:nrow(bb),3:ncol(bb)], method = "euclidean")

根据计算出的距离矩阵,我创建一个列表,显示每个点之间的距离。

library(reshape2)
df=melt(as.matrix(dis), varnames = c("row", "col"))

由此,我创建一个循环来提取每个点的比较,并根据值进行标准化。然后我填写一个数据框,这样我就可以将它们全部放在一个来源中。

s=NULL
for(i in 1:10){
  w=df[df$row==i&df$col!=i,]
  w=w[order(w$value),]
  w[,3]=(w[,3]-min(w[,3]))/(max(w[,3])-min(w[,3])) # there are a few other computations as well, but not included here for simplicity
  s=rbind(s,w)
}

最后,我希望能够拥有一个可以在另一个具有此格式的程序中使用的表。

> head(s,10)
   row col      value
71   1   8 0.00000000
61   1   7 0.08982679
41   1   5 0.25082060
31   1   4 0.42078163
11   1   2 0.53509305
21   1   3 0.61867437
51   1   6 0.67420271
81   1   9 0.69711889
91   1  10 1.00000000
22   2   3 0.00000000

我的实际数据有3K行和1.2k列,处理时间非常慢。是否有更有效的方法在数据帧的某些子集df上执行计算,这样我最终会得到相同的结果。

我听说for循环不应该用于增长数据框架,所以如果有更有效的方法,我很好奇。

1 个答案:

答案 0 :(得分:1)

你可能最好开始考虑矢量化模式 您正在做的是对涉及同一行上其他值的每一行执行操作,或者对maxmin这样的简单聚合执行操作。

dplyrdata.table可帮助您这样做。

使用dplyr

# Take only the rows where col is different from row
df <- filter(.data = df, row != col)

# Group by the col variable, usedto isolate each group
df <- group_by(.data = df, col)

# Create a new var 'value2' with the result of the operation
# Note that min and max refers only to the specific group
df <- mutate(.data = df, value2 = (value-min(value))/(max(value) - min(value)))

dplyr的好处是你可以使用%>%连接这些步骤,其中下一个函数的第一个参数(.data)是上一个操作的结果: / p>

df %>% 
    filter(row != col) %>% 
    group_by(col) %>% 
    mutate(value2 = (value-min(value))/(max(value) - min(value)))

使用data.table

df <- data.table(df)
df[row!=col, .(value2 = (value-min(value))/(max(value) - min(value))), by=col]

[请注意我data.table并不是那么好,可能有更好的方法可以做到这一点]