假设我们有5个数据帧,其中一列基于相同的时间戳("年");每个都有可能有不同数量的行和列,但每个都有一个名为year的第一列。每个开始和结束在不同的年份,因此所有数据帧中没有共同的开始或结束日期。我们希望根据收集这些数据的年份将所有数据帧组合成一个(即,在特定年份的一个矩阵中收集的数据,对应于同一年的其他数据帧中的数据)。对于那些没有相应年份的数据帧,我们希望用NA填充这些空白。
我们如何排列数据并将它们合并为一个数据框?
假设为了论证,我们有以下数据帧:
M1 <- data.frame(year=2000:2010, v1=16:26, v2=25:35)
M1; dim(M1) # 11x3
M2 <- data.frame(year=2005:2018, v3=6:19, v4=5:18, v5=3:16)
M2; dim(M2) #14x4
M3 <- data.frame(year=2002:2016, v3=3:17, v6=2:16, v7=0:14)
M3; dim(M3) # 15x4
M4 <- data.frame(year=2008:2020, v3=9:21, v6=8:20, v8=6:18)
M4; dim(M4) # 13x4
M5 <- data.frame(year=2018:2020, v9=19:21, v10=18:20, v11=16:18, v12=29:31)
M5; dim(M5) # 3x5
注意:另一个useR询问了一个非常相似的问题,并且由推理结束&#34;不清楚&#34;。我整整地澄清了他的问题。
答案 0 :(得分:3)
我认为使用full_join
的{{1}}命令效率更高。每次需要加入新数据帧时,您都可以使用dplyr
,或者在full_join
函数中使用一次,以便按顺序工作。请参阅以下两种方法:
reduce
第一种方法:
# create example datasets
M1 <- data.frame(year=2000:2010, v1=16:26, v2=25:35)
M2 <- data.frame(year=2005:2018, v3=6:19, v4=5:18, v5=3:16)
M3 <- data.frame(year=2002:2016, v3=3:17, v6=2:16, v7=0:14)
M4 <- data.frame(year=2008:2020, v3=9:21, v6=8:20, v8=6:18)
M5 <- data.frame(year=2018:2020, v9=19:21, v10=18:20, v11=16:18, v12=29:31)
第二种方法:
library(dplyr)
# use the full_join command
# you have to "manually" use a full_join command for every new dataset you want to join
full_join(M1, M2, by="year") %>%
full_join(M3, by="year") %>%
full_join(M4, by="year") %>%
full_join(M5, by="year")
# year v1 v2 v3.x v4 v5 v3.y v6.x v7 v3 v6.y v8 v9 v10 v11 v12
# 1 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA
# 2 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA
# 3 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA
# 4 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA
# 5 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA
# 6 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA
# 7 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA
# 8 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA
# 9 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA
# 10 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA
# 11 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA
# 12 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA
# 13 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA
# 14 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA
# 15 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA
# 16 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA
# 17 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA
# 18 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA
# 19 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29
# 20 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30
# 21 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31
答案 1 :(得分:2)
你可以这样做,
Reduce(function(x, y)merge(x, y, by = 'year', all = TRUE), mget(ls(pattern = 'M[0-9]+')))
给出,
year v1 v2 v3.x v4 v5 v3.y v6.x v7 v3 v6.y v8 v9 v10 v11 v12 1 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA 2 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA 3 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA 4 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA 5 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA 6 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA 7 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA 8 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA 9 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA 10 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA 11 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA 12 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA 13 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA 14 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA 15 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA 16 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA 17 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA 18 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA 19 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29 20 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30 21 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31
答案 2 :(得分:2)
某些数据框确实具有相同的列名。因此,同一年份和列名称可能有不同的值。
因此,我建议rbindlist()
所有数据框,并使用melt()
和dcast()
使用适当的聚合函数,这将使这些&#34;重复&#34;条目可见:
df_list <- mget(paste0("M", 1:5))
library(datat.table)
rbindlist(df_list, use.names = TRUE, fill = TRUE, idcol = "df")[
, melt(.SD, id.vars = c("df", "year"), na.rm = TRUE)][
, dcast(.SD, year ~ variable, function(x) toString(unique(x)))]
year v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 1: 2000 16 25 2: 2001 17 26 3: 2002 18 27 3 2 0 4: 2003 19 28 4 3 1 5: 2004 20 29 5 4 2 6: 2005 21 30 6 5 3 5 3 7: 2006 22 31 7 6 4 6 4 8: 2007 23 32 8 7 5 7 5 9: 2008 24 33 9 8 6 8 6 6 10: 2009 25 34 10 9 7 9 7 7 11: 2010 26 35 11 10 8 10 8 8 12: 2011 12 11 9 11 9 9 13: 2012 13 12 10 12 10 10 14: 2013 14 13 11 13 11 11 15: 2014 15 14 12 14 12 12 16: 2015 16 15 13 15 13 13 17: 2016 17 16 14 16 14 14 18: 2017 18 17 15 17 15 19: 2018 19 18 16 18 16 19 18 16 29 20: 2019 20 19 17 20 19 17 30 21: 2020 21 20 18 21 20 18 31 year v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12
或者,源数据框的名称可用于使列名称唯一:
rbindlist(df_list, use.names = TRUE, fill = TRUE, idcol = "df")[
, melt(.SD, id.vars = c("df", "year"), na.rm = TRUE)][
, dcast(.SD, year ~ paste(variable, df, sep = "_"))]
year v10_M5 v11_M5 v12_M5 v1_M1 v2_M1 v3_M2 v3_M3 v3_M4 v4_M2 v5_M2 v6_M3 v6_M4 v7_M3 v8_M4 v9_M5 1: 2000 NA NA NA 16 25 NA NA NA NA NA NA NA NA NA NA 2: 2001 NA NA NA 17 26 NA NA NA NA NA NA NA NA NA NA 3: 2002 NA NA NA 18 27 NA 3 NA NA NA 2 NA 0 NA NA 4: 2003 NA NA NA 19 28 NA 4 NA NA NA 3 NA 1 NA NA 5: 2004 NA NA NA 20 29 NA 5 NA NA NA 4 NA 2 NA NA 6: 2005 NA NA NA 21 30 6 6 NA 5 3 5 NA 3 NA NA 7: 2006 NA NA NA 22 31 7 7 NA 6 4 6 NA 4 NA NA 8: 2007 NA NA NA 23 32 8 8 NA 7 5 7 NA 5 NA NA 9: 2008 NA NA NA 24 33 9 9 9 8 6 8 8 6 6 NA 10: 2009 NA NA NA 25 34 10 10 10 9 7 9 9 7 7 NA 11: 2010 NA NA NA 26 35 11 11 11 10 8 10 10 8 8 NA 12: 2011 NA NA NA NA NA 12 12 12 11 9 11 11 9 9 NA 13: 2012 NA NA NA NA NA 13 13 13 12 10 12 12 10 10 NA 14: 2013 NA NA NA NA NA 14 14 14 13 11 13 13 11 11 NA 15: 2014 NA NA NA NA NA 15 15 15 14 12 14 14 12 12 NA 16: 2015 NA NA NA NA NA 16 16 16 15 13 15 15 13 13 NA 17: 2016 NA NA NA NA NA 17 17 17 16 14 16 16 14 14 NA 18: 2017 NA NA NA NA NA 18 NA 18 17 15 NA 17 NA 15 NA 19: 2018 18 16 29 NA NA 19 NA 19 18 16 NA 18 NA 16 19 20: 2019 19 17 30 NA NA NA NA 20 NA NA NA 19 NA 17 20 21: 2020 20 18 31 NA NA NA NA 21 NA NA NA 20 NA 18 21 year v10_M5 v11_M5 v12_M5 v1_M1 v2_M1 v3_M2 v3_M3 v3_M4 v4_M2 v5_M2 v6_M3 v6_M4 v7_M3 v8_M4 v9_M5
答案 3 :(得分:0)
步骤1:在考虑所有数据框的情况下找出最小和最大年份:
min(M1["year"], M2["year"], M3["year"], M4["year"], M5["year"]) # 2000
max(M1["year"], M2["year"], M3["year"], M4["year"], M5["year"]) # 2020
步骤2:通过抽取相关的NA来扩展M1到M5,并在开始和结束时注意缺失的年份
M1NA <- rbind(M1, data.frame(year=2011:2020, v1=NA, v2=NA))
M1NA
M2NA <- rbind(data.frame(year=2000:2004, v3=NA, v4=NA, v5=NA), M2, data.frame(year=2019:2020, v3=NA, v4=NA, v5=NA))
M2NA
M3NA <- rbind(data.frame(year=2000:2001, v3=NA, v6=NA, v7=NA), M3, data.frame(year=2017:2020, v3=NA, v6=NA, v7=NA))
M3NA
M4NA <- rbind(data.frame(year=2000:2007, v3=NA, v6=NA, v8=NA), M4)
M4NA
M5NA <- rbind(data.frame(year=2000:2017, v9=NA, v10=NA, v11=NA, v12=NA), M5)
M5NA
步骤3:在最终数据帧中合并NA'ed数据帧;无需在其他数据框中重复年份列,因此删除它们。
CombinedFrame <- cbind(M1NA, M2NA[-1], M3NA[-1], M4NA[-1], M5NA[-1])
CombinedFrame
如果是矩阵,请执行以下操作:
通过以下任一方式将结果数据帧转换为矩阵:
CombinedMatrix <- as.matrix(sapply(CombinedFrame, as.numeric))
CombinedMatrix
CombinedMatrix <- matrix(as.numeric(unlist(CombinedFrame)),nrow=nrow(CombinedFrame))
CombinedMatrix
注意:上述转换考虑了数据帧中字符串存在的可能性(即开头的矩阵)
这会产生以下内容(正如所需):
year v1 v2 v3 v4 v5 v3 v6 v7 v3 v6 v8 v9 v10 v11 v12
[1,] 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA
[2,] 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA
[3,] 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA
[4,] 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA
[5,] 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA
[6,] 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA
[7,] 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA
[8,] 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA
[9,] 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA
[10,] 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA
[11,] 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA
[12,] 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA
[13,] 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA
[14,] 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA
[15,] 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA
[16,] 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA
[17,] 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA
[18,] 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA
[19,] 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29
[20,] 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30
[21,] 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31