如何优化for循环以填充数据帧R
我有一个数据框,在这里我计算一个距离矩阵如何优化for循环以填充数据帧R,r,for-loop,optimization,dataframe,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") 在此基础上,我创建了一个循环来提取每个点的比较,并基于这些值进行规范化。然后,我填充一个数据帧,以便在单个源中获取所有数据 s=NULL for(i i
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")
在此基础上,我创建了一个循环来提取每个点的比较,并基于这些值进行规范化。然后,我填充一个数据帧,以便在单个源中获取所有数据
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循环不应该用于增长数据帧,所以我很好奇是否有更有效的方法来实现这一点。您最好开始以矢量化模式思考。
您所做的是在每一行上执行一个操作,该操作涉及同一行上的其他值,或者简单的聚合,如
max
和min
包dplyr
或data.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)))
带有
数据。表:
df <- data.table(df)
df[row!=col, .(value2 = (value-min(value))/(max(value) - min(value))), by=col]
df“我听说for循环不应该用于增长数据帧”:它更像。创建具有最终大小的对象并填充它(如果您愿意,可以使用循环)您可以使用s预定义数据帧。为了结束,我做了一些基准测试。我的上路:23.2s,@Cath等人建议:6.0s
df %>%
filter(row != col) %>%
group_by(col) %>%
mutate(value2 = (value-min(value))/(max(value) - min(value)))
df <- data.table(df)
df[row!=col, .(value2 = (value-min(value))/(max(value) - min(value))), by=col]