我有两个数据框tab1
和tab2
。他们看起来像这样:
#tab1
"ID" "grp" "DV" "dat2" ..... "dat"
1 1 (some data) NA
2 1 (some data) NA
3 1 (some data) NA
4 2 (some data) NA
5 2 (some data) NA
6 2 (some data) NA
7 3 (some data) NA
....
6e+7 6e+4(some data) NA #approx, actual size not shown
#tab2
"grp" "dat"
1 123
2 456
3 234
....
6e+4 567 #approx, actual size not shown
tab1
中的“dat”列不存在。我最初的想法是将值从tab2
复制到tab1
,以便tab1
看起来像:
#tab1
"ID" "grp" "DV" "dat2" ..... "dat"
1 1 (some data) 123
2 1 (some data) 123
3 1 (some data) 123
4 2 (some data) 456
5 2 (some data) 456
6 2 (some data) 456
7 3 (some data) 234
....
6e+7 6e+4(some data) 567 #approx, actual size not shown
然后使用tab1
进行回归。
我使用以下代码完成了它,但结果是非常慢(这对我没有意义,因为我希望将值复制到指定的索引应该非常快......):
for(i in 1:6e+4) {
tab1[tab1$grp==i, "dat"] <- tab2[i,2]
if(i%%100==0) cat(paste("\n", i, "/", 6e+4, sep="")) # progress display
}
然后我意识到:
我有很多列要以这种方式复制,所以这似乎效率低下......
由于tab1
有数百万行,因此会产生异常大的数据框
更重要的是,也许我可以使用跨不同数据框架的数据进行回归?但我不知道该怎么做。 (感觉这应该是出路)
感谢您参与我的问题!
编辑:
可重现的例子: https://gist.github.com/anonymous/1c93af8fe810a209b5ad54fb1b86d4c4
答案 0 :(得分:0)
有几种方法可以在R中分配一个列,for
循环不是最快的,所以我建议您使用data.table
,而在下面你会看到原因。
require(data.table)
require(ggplot) #for nice plot
require(microbenchmark)
foo_loop <- function(){
for(i in 1:10) {
tab1[tab1$grp==i,"dat"] <- tab2[i,2]
}
}
foo_base <- function(){
tab1$dat = tab2[,2]
}
foo_DT <- function(){
#fastest solution
tab1[,dat := tab2$dat]
}
res <- microbenchmark(foo_loop(),foo_base(),foo_DT,times = 1e4)
autoplot(res)
答案 1 :(得分:0)
感谢可重复的例子。我的建议如下(使用tidyverse中的包):
rm(list = ls())
library(tidyverse)
tab1$dat <- NULL #We won't need this column, since we will get it from tab2
tab_1_new <- tab1 %>% dplyr::inner_join(tab2, by = c("grp" = "grp")