我有一个庞大的数据集,但要问我的问题,我创建简化的数据..
我想根据一个数据的一列信息和其他数据的变量名称合并两个不同的数据库。
d1 <- data.frame(subject = c(1,1,1,1,1,1,2,2,2,2,2,2),stime=c('4/16/2012','4/17/2012','4/18/2012','4/19/2012','4/20/2012','4/21/2012','4/16/2012','4/17/2012','4/18/2012','4/19/2012','4/20/2012','4/21/2012'))
d2 <- data.frame(x1 = c(11.5,12.3,22,34,25,35),x2=c(4,16,23,25,33,45),stime=c('4/16/2012','4/17/2012','4/18/2012','4/19/2012','4/20/2012','4/21/2012'))
> d1
subject stime
1 1 4/16/2012
2 1 4/17/2012
3 1 4/18/2012
4 1 4/19/2012
5 1 4/20/2012
6 1 4/21/2012
7 2 4/16/2012
8 2 4/17/2012
9 2 4/18/2012
10 2 4/19/2012
11 2 4/20/2012
12 2 4/21/2012
> d2
x1 x2 stime
1 11.5 4 4/16/2012
2 12.3 16 4/17/2012
3 22.0 23 4/18/2012
4 34.0 25 4/19/2012
5 25.0 33 4/20/2012
6 35.0 45 4/21/2012
基本上,我想创建这样的数据.. 这意味着我想基于d2的变量名称合并这些数据,例如x1,x2和来自d1的“主题”的信息。 可能吗?请帮帮我..非常感谢你!
subject stime Variable
1 1 4/16/2012 11.5
2 1 4/17/2012 12.3
3 1 4/18/2012 22.0
4 1 4/19/2012 34.0
5 1 4/20/2012 25.0
6 1 4/21/2012 35.0
7 2 4/16/2012 4
8 2 4/17/2012 16
9 2 4/18/2012 23
10 2 4/19/2012 25
11 2 4/20/2012 33
12 2 4/21/2012 45
答案 0 :(得分:4)
到目前为止,所有答案都以某种方式将d2
转换为长格式,然后执行合并。这导致为(中间)熔融数据分配内存,并再次为最终merge/join
分配内存。既然你提到巨大的数据(但没有提到维度),我假设优化速度 和 内存是最理想的。
以下是:
require(data.table) ## 1.9.4+
setkey(setDT(d2), stime)
setDT(d1)
get_cols = function(d1_subject, d1_time) {
d2[J(d1_time), list(stime, var = if (d1_subject==1) x1 else x2)]
}
d1[, get_cols(subject, stime), by=subject]
# subject stime var
# 1: 1 4/16/2012 11.5
# 2: 1 4/17/2012 12.3
# 3: 1 4/18/2012 22.0
# 4: 1 4/19/2012 34.0
# 5: 1 4/20/2012 25.0
# 6: 1 4/21/2012 35.0
# 7: 2 4/16/2012 4.0
# 8: 2 4/17/2012 16.0
# 9: 2 4/18/2012 23.0
# 10: 2 4/19/2012 25.0
# 11: 2 4/20/2012 33.0
# 12: 2 4/21/2012 45.0
我们首先使用setDT()
函数将data.frames转换为data.tables。然后我们将 d2
的关键列设置为stime
,按行按顺序对 d2
进行排序,并标记为列为键列,我们将在下一步中加入。
在下一步中,我们首先按d1
分组subject
,为每个分组分组,我们调用get_cols
函数subject
来自stime
的{和d1
值与 组相对应。对于每个群组,我们使用与d2
对应的stime
对应的值d1_time
在d1$stime
的关键列subject
上执行加入 {1}}我们根据x1
提取列x2
或subject == 1 or 2
。
这里,来自melt
的中间结果从未实现,因此内存效率很高,并且使用二进制搜索快速连接。
答案 1 :(得分:3)
使用tidyr
和dplyr
:
来自@docendodiscimus关于更惯用解决方案的建议
library(tidyr)
library(dplyr)
gather(d2, subject, value, x1:x2) %>%
mutate(subject = as.numeric(gsub("^x", "", subject))) %>%
inner_join(., d1)
#Joining by: c("stime", "subject")
# stime subject value
#1 4/16/2012 1 11.5
#2 4/17/2012 1 12.3
#3 4/18/2012 1 22.0
#4 4/19/2012 1 34.0
#5 4/20/2012 1 25.0
#6 4/21/2012 1 35.0
#7 4/16/2012 2 4.0
#8 4/17/2012 2 16.0
#9 4/18/2012 2 23.0
#10 4/19/2012 2 25.0
#11 4/20/2012 2 33.0
#12 4/21/2012 2 45.0
答案 2 :(得分:2)
你正在做的事情是融合和融合的结合。真的只是融化d2
似乎回归你想要的
library(reshape2)
melt(d2)
当然你会得到专栏&#34;变量&#34;子集名称与&#34; x&#34;结合使用。但您可以将其他ID转换为包含&#34; x&#34;然后合并
mm <- merge(transform(d1, variable=paste0("x",subject)), melt(d2))
mm
# stime variable subject value
# 1 4/16/2012 x1 1 11.5
# 2 4/16/2012 x2 2 4.0
# 3 4/17/2012 x1 1 12.3
# 4 4/17/2012 x2 2 16.0
# 5 4/18/2012 x1 1 22.0
# 6 4/18/2012 x2 2 23.0
# 7 4/19/2012 x1 1 34.0
# 8 4/19/2012 x2 2 25.0
# 9 4/20/2012 x1 1 25.0
# 10 4/20/2012 x2 2 33.0
# 11 4/21/2012 x1 1 35.0
# 12 4/21/2012 x2 2 45.0
如果你想借助并删除额外的列,你可以
subset(mm[order(mm$subject),], select=-variable)
答案 3 :(得分:1)
使用melt
和merge
的组合可以实现所需的结果。
library(reshape)
colnames(d2)<-c("1","2","stime") #change the column names from "x1","x2" to "1","2"
我们在melt
上使用d2
。 id
变量stime
保持不变,而使用其他列形成新列subject
。
x2 <- melt(d2,id=c("stime"),variable_name="subject")
#>x2
# stime subject value
#1 4/16/2012 1 11.5
#2 4/17/2012 1 12.3
#3 4/18/2012 1 22.0
#4 4/19/2012 1 34.0
#5 4/20/2012 1 25.0
#6 4/21/2012 1 35.0
#7 4/16/2012 2 4.0
#8 4/17/2012 2 16.0
#9 4/18/2012 2 23.0
#10 4/19/2012 2 25.0
#11 4/20/2012 2 33.0
#12 4/21/2012 2 45.0
我们现在可以通过公共变量merge
和d1
x2
subject
和stime
来获得所需的结果。
dd2 <- merge(d1, x2, by=c("subject","stime"))
#> dd2
# subject stime value
#1 1 4/16/2012 11.5
#2 1 4/17/2012 12.3
#3 1 4/18/2012 22.0
#4 1 4/19/2012 34.0
#5 1 4/20/2012 25.0
#6 1 4/21/2012 35.0
#7 2 4/16/2012 4.0
#8 2 4/17/2012 16.0
#9 2 4/18/2012 23.0
#10 2 4/19/2012 25.0
#11 2 4/20/2012 33.0
#12 2 4/21/2012 45.0