如何对来自不同数据框的变量进行回归分析
How to do regression analyses with variables from different data frames
我有两个数据框,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
在 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)
感谢您提供可重现的示例。我的建议如下(使用 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")
我有两个数据框,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
在 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)
感谢您提供可重现的示例。我的建议如下(使用 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")