【问题标题】:Merging two dataframes creates new missing observations合并两个数据框会创建新的缺失观测值
【发布时间】:2020-07-02 05:26:42
【问题描述】:

我有两个具有以下匹配键的数据框:年份、地区和省份。它们每个都有一组变量(在这个说明性示例中,我使用 x1 表示 df1,x2 表示 df2),并且两个变量本身都有几个缺失值。

             df1                                             df2
year   region   province   x2  ... xn             year   region   province     x2 ... xn
2019    1          5       NA              2019    1          5         NA
2019    2          4       NA.             2019    2          4         NA.  
2019    2          4       NA.             2019    2          4         NA
2018    3          7       13.             2018    3          7         13
2018    3          7       15              2018    3          7         15
2018    3          7       17              2018    3          7         17

我想合并两个数据框,使它们最终变成这样:

year   region   province   x1   x2
2019    1          5        3   NA
2019    2          4       27   NA
2019    2          4       15   NA
2018    3          7       12   13
2018    3          7       NA   15
2018    3          7       NA   17
2017    4          9       NA   12
2017    4          9       19   30
2017    4          9       20   10

但是,当使用merged_df <- merge(df1, df2, by=c("year","region","province"), all.x=TRUE) 执行此操作时,R 似乎在每个变量列(x1 和 x2)上创建了许多额外的缺失值,这是以前不存在的。这里发生了什么?我已经尝试使用df1 %>% arrange(province,-year) 和df2 %>% arrange(province,-year) 进行排序,这足以在两个数据框中具有匹配的顺序,只是在运行merge 命令时发现相同的问题。我也尝试了很多其他的东西,但似乎没有任何效果。 R 的输出如下所示:

year   region   province   x1   x2
2019    1          5       NA   NA
2019    2          4       NA   NA
2019    2          4       NA   NA
2018    3          7       NA   NA
2018    3          7       NA   NA
2018    3          7       NA   NA
2017    4          9       15   NA
2017    4          9       19   30
2017    4          9       20   10

我以前做过这个;事实上,其中一个数据框是一个已经合并的数据框,我没有遇到这个问题。

【问题讨论】:

  • 我在您的 `by` 列上看到许多重复项,因此这不是主键。这就解释了看似奇怪的结果。
  • @Edward 我知道他们,但看起来仍然很奇怪。数据框是故意这样构造的;它们包含每个省的若干年度观察结果,并且每个省(在大多数情况下,不止一个)都是一个区域的一部分。我刚刚在 Stata 上执行了相同的操作,它完成它没有任何问题,考虑到我不喜欢那种环境,这令人沮丧。很抱歉没有发布 reprex 或正确的格式 - 我是 R 和 Stack Overflow 的新手
  • Stata 命令是什么?
  • @Edward 使用 df2.dta 合并 1:1 省份区域年份;在加载 df1 时执行
  • @Edward 所以如果不麻烦的话,请问什么是正确的方法?

标签: r dataframe merge


【解决方案1】:

可能merge()的概念不清楚。我包括两个带有示例数据的示例。希望你能理解,对你有帮助。

#Data
set.seed(123)
DF1 <- data.frame(year=rep(c(2017,2018,2019),3),
                  region=rep(c(1,2,3),3),
                  province=round(runif(9,1,5),0),
                  x1=rnorm(9,3,1.5))
DF2 <- data.frame(year=rep(c(2016,2018,2019),3),
                  region=rep(c(1,2,3),3),
                  province=round(runif(9,1,5),0),
                  x2=rnorm(9,3,1.5))

#Merge based only in df1
Merged1 <- merge(DF1,DF2,by=intersect(names(DF1),names(DF2)),all.x=T)

Merged1
  year region province        x1       x2
1 2017      1        2 2.8365510       NA
2 2017      1        3 3.7557187       NA
3 2017      1        5 4.9208323       NA
4 2018      2        4 2.8241371       NA
5 2018      2        5 6.7925048 1.460993
6 2018      2        5 0.4090941 1.460993
7 2019      3        1 5.5352765       NA
8 2019      3        3 3.8236451 4.256681
9 2019      3        3 3.2746239 4.256681

#Merge including all elements despite no match between ids
Merged2 <- merge(DF1,DF2,by=intersect(names(DF1),names(DF2)),all = T)

Merged2
   year region province        x1       x2
1  2016      1        3        NA 4.052034
2  2016      1        4        NA 2.062441
3  2016      1        5        NA 2.673038
4  2017      1        2 2.8365510       NA
5  2017      1        3 3.7557187       NA
6  2017      1        5 4.9208323       NA
7  2018      2        1        NA 0.469960
8  2018      2        2        NA 2.290813
9  2018      2        4 2.8241371       NA
10 2018      2        5 6.7925048 1.460993
11 2018      2        5 0.4090941 1.460993
12 2019      3        1 5.5352765       NA
13 2019      3        2        NA 1.398264
14 2019      3        3 3.8236451 4.256681
15 2019      3        3 3.2746239 4.256681
16 2019      3        4        NA 1.906663

【讨论】:

  • 哇,完美运行!您是否愿意开发并解释为什么 Merged1 &lt;- merge(DF1,DF2,by=intersect(names(DF1),names(DF2)),all.x=T) 工作,但 merged_df &lt;- merge(df1, df2, by=c("year","region","province"), all.x=TRUE) 搞砸了输出?
  • @Kamyen 嗨。可能是由于每个数据框的名称。您必须检查所有名称是否相等,以便在合并的 by 参数中定义为键。 names(DF1) 为您提供该输出。有时名称有空格或者可以是不同的类型,如numeric 或因子。希望这会有所帮助。
  • 谢谢,所以如果是列名不匹配的情况,那么如果我理解正确的话,你说的命令不管键是否匹配都会合并?
  • @Kamyen intersect() 将在所有数据帧之间找到通用名称,以便可以完成合并。您可以尝试更改名称的虚拟数据集以更好地理解:)
  • @Kamyen 欢迎您。如果你觉得这个答案有用,你可以接受它:)
猜你喜欢
  • 1970-01-01
  • 2014-08-17
  • 2018-02-21
  • 2022-11-18
  • 2022-11-03
  • 2020-10-28
  • 2019-11-29
  • 1970-01-01
  • 2012-11-25
相关资源
最近更新 更多