使用 dplyr 合并数据集和合并列 R
Using dplyr to merge datasets and consolidate columns R
我有两个要合并的数据集。它们不是完整的数据集,因此这意味着个人缺少记录。
这里是data1
(示例是我真实数据的一个子集):
squirrel_id age ageclass trialdate year OFT1 MIS1
10342 1 Y 2008-05-19 2008 0.605 -4.19
10342 2 A 2009-05-31 2009 -1.85 1.14
10342 3 A 2010-05-22 2010 -2.39 2.38
这里是data2
(示例是我真实数据的一个子集):
squirrel_id focal_age focal_ageclass focal_date focal_yr PC1 PC2
10342 1 Y 2008-07-14 2008 0.0932 -2.67
10342 3 A 2010-03-13 2010 -2.38 0.216
10342 3 A 2010-04-20 2010 0.0203 1.80
我正在尝试做两件事:
- 合并这两个数据集,以便在记录不完整时保留 NA(即,
data1
在 age==3
有 1 条记录,而 data2
在 [=18= 时有 2 条记录])
- 合并列使数据集更精简(即数据集中不同名称的列代表相同的事物:
age==focal_age
、ageclass==focal_ageclass
、trialnumber==focalseq
、ageclass==focal_ageclass
, year==focal_yr
)
所需的输出 - 我试图得到一个看起来像这样的最终数据集(其中 age==3
的 data1
记录只显示一次,不是两次):
squirrel_id age ageclass date year OFT1 MIS1 PC1 PC2
10342 1 Y 2008-05-19 2008 0.605 -4.19 NA NA
10342 1 Y 2008-07-14 2008 NA NA 0.0932 -2.67
10342 2 A 2009-05-31 2009 -1.85 1.14 NA NA
10342 3 A 2010-05-22 2010 -2.39 2.38 NA NA
10342 3 A 2010-03-13 2010 NA NA -2.38 0.216
10342 3 A 2010-04-20 2010 NA NA 0.0203 1.80
我可以通过以下方式到达这里:
data3<-full_join(data1, data2,
by=c("squirrel_id"="squirrel_id",
"year"="focal_yr",
"age"="focal_age",
"ageclass"="focal_ageclass"))
但这会为 data2
中的两个 age==3
行重复 age==3
的 data1
值(而不是仅匹配第一行),给出此 (不需要) 输出:
squirrel_id age ageclass trialdate focal_date year OFT1 MIS1 PC1 PC2
10342 1 Y 2008-05-19 2008-07-14 2008 0.605 -4.19 0.0932 -2.67
10342 2 A 2009-05-31 NA 2009 -1.85 1.14 NA NA
10342 3 A 2010-05-22 2010-03-13 2010 -2.39 2.38 -2.38 0.216
10342 3 A 2010-05-22 2010-04-20 2010 -2.39 2.38 0.0203 1.80
更新问题: 如何让匹配记录在执行 full_join
时为所有行添加 NA? 注意我宁愿 dplyr
解决方案,因为我不在 data.table
工作(就像对 ) and I want to retain the rows that don't match (unlike 的回答)。
这是一个data.table
方法
示例数据
library(data.table)
data1 <- fread("squirrel_id age ageclass trialdate year OFT1 MIS1
10342 1 Y 2008-05-19 2008 0.605 -4.19
10342 2 A 2009-05-31 2009 -1.85 1.14
10342 3 A 2010-05-22 2010 -2.39 2.38")
data2 <- fread("squirrel_id focal_age focal_ageclass focal_date focal_yr PC1 PC2
10342 1 Y 2008-07-14 2008 0.0932 -2.67
10342 3 A 2010-03-13 2010 -2.38 0.216
10342 3 A 2010-04-20 2010 0.0203 1.80 ")
代码
# Assuming the first five columns can be rowbound without problem,
# melt them to long
L <- lapply(list(data1, data2), melt, id.vars = 1:5)
# squirrel_id age ageclass trialdate year variable value
# 1: 10342 1 Y 2008-05-19 2008 OFT1 0.605
# 2: 10342 2 A 2009-05-31 2009 OFT1 -1.850
# 3: 10342 3 A 2010-05-22 2010 OFT1 -2.390
# 4: 10342 1 Y 2008-05-19 2008 MIS1 -4.190
# 5: 10342 2 A 2009-05-31 2009 MIS1 1.140
# 6: 10342 3 A 2010-05-22 2010 MIS1 2.380
#
# [[2]]
# squirrel_id focal_age focal_ageclass focal_date focal_yr variable value
# 1: 10342 1 Y 2008-07-14 2008 PC1 0.0932
# 2: 10342 3 A 2010-03-13 2010 PC1 -2.3800
# 3: 10342 3 A 2010-04-20 2010 PC1 0.0203
# 4: 10342 1 Y 2008-07-14 2008 PC2 -2.6700
# 5: 10342 3 A 2010-03-13 2010 PC2 0.2160
# 6: 10342 3 A 2010-04-20 2010 PC2 1.8000
# Rowbind, ignore columnnames
DT <- data.table::rbindlist(L, use.names = FALSE, fill = FALSE)
# squirrel_id age ageclass trialdate year variable value
# 1: 10342 1 Y 2008-05-19 2008 OFT1 0.6050
# 2: 10342 2 A 2009-05-31 2009 OFT1 -1.8500
# 3: 10342 3 A 2010-05-22 2010 OFT1 -2.3900
# 4: 10342 1 Y 2008-05-19 2008 MIS1 -4.1900
# 5: 10342 2 A 2009-05-31 2009 MIS1 1.1400
# 6: 10342 3 A 2010-05-22 2010 MIS1 2.3800
# 7: 10342 1 Y 2008-07-14 2008 PC1 0.0932
# 8: 10342 3 A 2010-03-13 2010 PC1 -2.3800
# 9: 10342 3 A 2010-04-20 2010 PC1 0.0203
#10: 10342 1 Y 2008-07-14 2008 PC2 -2.6700
#11: 10342 3 A 2010-03-13 2010 PC2 0.2160
#12: 10342 3 A 2010-04-20 2010 PC2 1.8000
# Cast to wide again
dcast(DT, ... ~ variable, value.var = "value")
# squirrel_id age ageclass trialdate year OFT1 MIS1 PC1 PC2
# 1: 10342 1 Y 2008-05-19 2008 0.605 -4.19 NA NA
# 2: 10342 1 Y 2008-07-14 2008 NA NA 0.0932 -2.670
# 3: 10342 2 A 2009-05-31 2009 -1.850 1.14 NA NA
# 4: 10342 3 A 2010-03-13 2010 NA NA -2.3800 0.216
# 5: 10342 3 A 2010-04-20 2010 NA NA 0.0203 1.800
# 6: 10342 3 A 2010-05-22 2010 -2.390 2.38 NA NA
我有两个要合并的数据集。它们不是完整的数据集,因此这意味着个人缺少记录。
这里是data1
(示例是我真实数据的一个子集):
squirrel_id age ageclass trialdate year OFT1 MIS1
10342 1 Y 2008-05-19 2008 0.605 -4.19
10342 2 A 2009-05-31 2009 -1.85 1.14
10342 3 A 2010-05-22 2010 -2.39 2.38
这里是data2
(示例是我真实数据的一个子集):
squirrel_id focal_age focal_ageclass focal_date focal_yr PC1 PC2
10342 1 Y 2008-07-14 2008 0.0932 -2.67
10342 3 A 2010-03-13 2010 -2.38 0.216
10342 3 A 2010-04-20 2010 0.0203 1.80
我正在尝试做两件事:
- 合并这两个数据集,以便在记录不完整时保留 NA(即,
data1
在age==3
有 1 条记录,而data2
在 [=18= 时有 2 条记录]) - 合并列使数据集更精简(即数据集中不同名称的列代表相同的事物:
age==focal_age
、ageclass==focal_ageclass
、trialnumber==focalseq
、ageclass==focal_ageclass
,year==focal_yr
)
所需的输出 - 我试图得到一个看起来像这样的最终数据集(其中 age==3
的 data1
记录只显示一次,不是两次):
squirrel_id age ageclass date year OFT1 MIS1 PC1 PC2
10342 1 Y 2008-05-19 2008 0.605 -4.19 NA NA
10342 1 Y 2008-07-14 2008 NA NA 0.0932 -2.67
10342 2 A 2009-05-31 2009 -1.85 1.14 NA NA
10342 3 A 2010-05-22 2010 -2.39 2.38 NA NA
10342 3 A 2010-03-13 2010 NA NA -2.38 0.216
10342 3 A 2010-04-20 2010 NA NA 0.0203 1.80
我可以通过以下方式到达这里:
data3<-full_join(data1, data2,
by=c("squirrel_id"="squirrel_id",
"year"="focal_yr",
"age"="focal_age",
"ageclass"="focal_ageclass"))
但这会为 data2
中的两个 age==3
行重复 age==3
的 data1
值(而不是仅匹配第一行),给出此 (不需要) 输出:
squirrel_id age ageclass trialdate focal_date year OFT1 MIS1 PC1 PC2
10342 1 Y 2008-05-19 2008-07-14 2008 0.605 -4.19 0.0932 -2.67
10342 2 A 2009-05-31 NA 2009 -1.85 1.14 NA NA
10342 3 A 2010-05-22 2010-03-13 2010 -2.39 2.38 -2.38 0.216
10342 3 A 2010-05-22 2010-04-20 2010 -2.39 2.38 0.0203 1.80
更新问题: 如何让匹配记录在执行 full_join
时为所有行添加 NA? 注意我宁愿 dplyr
解决方案,因为我不在 data.table
工作(就像对
这是一个data.table
方法
示例数据
library(data.table)
data1 <- fread("squirrel_id age ageclass trialdate year OFT1 MIS1
10342 1 Y 2008-05-19 2008 0.605 -4.19
10342 2 A 2009-05-31 2009 -1.85 1.14
10342 3 A 2010-05-22 2010 -2.39 2.38")
data2 <- fread("squirrel_id focal_age focal_ageclass focal_date focal_yr PC1 PC2
10342 1 Y 2008-07-14 2008 0.0932 -2.67
10342 3 A 2010-03-13 2010 -2.38 0.216
10342 3 A 2010-04-20 2010 0.0203 1.80 ")
代码
# Assuming the first five columns can be rowbound without problem,
# melt them to long
L <- lapply(list(data1, data2), melt, id.vars = 1:5)
# squirrel_id age ageclass trialdate year variable value
# 1: 10342 1 Y 2008-05-19 2008 OFT1 0.605
# 2: 10342 2 A 2009-05-31 2009 OFT1 -1.850
# 3: 10342 3 A 2010-05-22 2010 OFT1 -2.390
# 4: 10342 1 Y 2008-05-19 2008 MIS1 -4.190
# 5: 10342 2 A 2009-05-31 2009 MIS1 1.140
# 6: 10342 3 A 2010-05-22 2010 MIS1 2.380
#
# [[2]]
# squirrel_id focal_age focal_ageclass focal_date focal_yr variable value
# 1: 10342 1 Y 2008-07-14 2008 PC1 0.0932
# 2: 10342 3 A 2010-03-13 2010 PC1 -2.3800
# 3: 10342 3 A 2010-04-20 2010 PC1 0.0203
# 4: 10342 1 Y 2008-07-14 2008 PC2 -2.6700
# 5: 10342 3 A 2010-03-13 2010 PC2 0.2160
# 6: 10342 3 A 2010-04-20 2010 PC2 1.8000
# Rowbind, ignore columnnames
DT <- data.table::rbindlist(L, use.names = FALSE, fill = FALSE)
# squirrel_id age ageclass trialdate year variable value
# 1: 10342 1 Y 2008-05-19 2008 OFT1 0.6050
# 2: 10342 2 A 2009-05-31 2009 OFT1 -1.8500
# 3: 10342 3 A 2010-05-22 2010 OFT1 -2.3900
# 4: 10342 1 Y 2008-05-19 2008 MIS1 -4.1900
# 5: 10342 2 A 2009-05-31 2009 MIS1 1.1400
# 6: 10342 3 A 2010-05-22 2010 MIS1 2.3800
# 7: 10342 1 Y 2008-07-14 2008 PC1 0.0932
# 8: 10342 3 A 2010-03-13 2010 PC1 -2.3800
# 9: 10342 3 A 2010-04-20 2010 PC1 0.0203
#10: 10342 1 Y 2008-07-14 2008 PC2 -2.6700
#11: 10342 3 A 2010-03-13 2010 PC2 0.2160
#12: 10342 3 A 2010-04-20 2010 PC2 1.8000
# Cast to wide again
dcast(DT, ... ~ variable, value.var = "value")
# squirrel_id age ageclass trialdate year OFT1 MIS1 PC1 PC2
# 1: 10342 1 Y 2008-05-19 2008 0.605 -4.19 NA NA
# 2: 10342 1 Y 2008-07-14 2008 NA NA 0.0932 -2.670
# 3: 10342 2 A 2009-05-31 2009 -1.850 1.14 NA NA
# 4: 10342 3 A 2010-03-13 2010 NA NA -2.3800 0.216
# 5: 10342 3 A 2010-04-20 2010 NA NA 0.0203 1.800
# 6: 10342 3 A 2010-05-22 2010 -2.390 2.38 NA NA