【问题标题】:How to merge these data frames如何合并这些数据框
【发布时间】:2019-03-19 12:19:52
【问题描述】:

我有两个 df,我需要合并它们。

df1 看起来像这样:

COUNTRY   YEAR   TRADE   
Spain     2016   276   
Germany   2016   323      
France    2016   392
Spain     2017   456   
Germany   2017   564      
France    2017   359
Spain     2015   767   
Germany   2015   868      
France    2015   969

df2 看起来像这样:

COUNTRY   GDP2016   GDP2017 GDP2015
Spain      1111       999    444
Germany    2222       888    555  
France     3333       777    666

我可以使用两个 GDP:

df3 <- merge(df1,df2, by = "COUNTRY")

df3 <- df3 %>% mutate(GDP = ifelse(YEAR == 2016, GDP2016, GDP2017))
df3 <- subset(df3, select = -c(GDP2016, GDP2017)

然而,对于 3 GDP,我必须使用不同的东西。我想得到的是:

COUNTRY   YEAR   TRADE    GDP 
Spain     2016   276      1111
Germany   2016   323      2222   
France    2016   392      3333
Spain     2017   456      999
Germany   2017   564      888      
France    2017   359      777
Spain     2015   767      444
Germany   2015   868      555      
France    2015   969      666

我将不胜感激!

【问题讨论】:

  • 上次我尝试过类似我建议它被否决的方法,但可能在两个数据集中都引入了一个新的 ID 列?
  • 你可以找到你的答案here

标签: r merge dplyr


【解决方案1】:

您必须melt df2 才能将其置于与df1 相同的格式。然后我通过删除字符串的“GDP”部分并仅保留年份来创建一个带有gsub 的新列 YEAR。

df2_melt <- melt(df2, id.vars="COUNTRY")
df2_melt$YEAR <- gsub(pattern = "GDP",replacement = "",x = df2_melt$variable)
colnames(df2_melt)[colnames(df2_melt)=="value"] <- "GDP"

df3 <- merge(df1,df2_melt, by = c("COUNTRY","YEAR"))

  COUNTRY YEAR TRADE variable  GDP
1  France 2016   392  GDP2016 3333
2  France 2017   359  GDP2017  777
3 Germany 2016   323  GDP2016 2222
4 Germany 2017   564  GDP2017  888
5   Spain 2016   276  GDP2016 1111
6   Spain 2017   456  GDP2017  999

数据

df1 <- read.table(text="COUNTRY   YEAR   TRADE   
Spain     2016   276   
Germany   2016   323      
France    2016   392
Spain     2017   456   
Germany   2017   564      
France    2017   359
Spain     2015   767   
Germany   2015   868      
France    2015   969",header=TRUE, stringsAsFactors=FALSE)

df2 <- read.table(text="COUNTRY   GDP2016   GDP2017 GDP2018
Spain      1111       999    444
Germany    2222       888    555  
France     3333       777    6669",header=TRUE, stringsAsFactors=FALSE)

【讨论】:

    【解决方案2】:

    你可以这样做:

    library(tidyverse)
    
    df1 %>%
      left_join(df2 %>%
                  gather(YEAR, GDP, -COUNTRY) %>%
                  mutate(YEAR = as.integer(sub("GDP", "", YEAR))),
                by = c("COUNTRY", "YEAR"))
    

    【讨论】:

      【解决方案3】:

      问题是 df2 不在一个易于加入的结构中,所以我将使用 tidyr 更改结构:

      library(dplyr)
      library(tidyr)
      
      df3 <-
        df1 %>% 
        left_join(df2 %>% 
                     gather(YEAR, GDP, -COUNTRY) %>% 
                     mutate(YEAR = as.numeric(substr(YEAR, 4, 7))), 
                   by = c("COUNTRY", "YEAR"))
      

      请注意,这并没有给出您预期的答案,因为年份不同。在 df1 中有 2015 年,但在 df2 中有 GDB2018 的数据。

      使用的数据:

      df1 <- tibble::tribble(
         ~COUNTRY, ~YEAR, ~TRADE,
          "Spain",  2016,    276,
        "Germany",  2016,    323,
         "France",  2016,    392,
          "Spain",  2017,    456,
        "Germany",  2017,    564,
         "France",  2017,    359,
          "Spain",  2015,    767,
        "Germany",  2015,    868,
         "France",  2015,    969
        )
      
      df2 <- tibble::tribble(
         ~COUNTRY, ~GDP2016, ~GDP2017, ~GDP2018,
          "Spain",     1111,      999,      444,
        "Germany",     2222,      888,      555,
         "France",     3333,      777,      666
        )
      

      【讨论】:

        【解决方案4】:

        数据表

        样本数据

        library( data.table )
        df1 <- fread("COUNTRY   YEAR   TRADE   
        Spain     2016   276   
                     Germany   2016   323      
                     France    2016   392
                     Spain     2017   456   
                     Germany   2017   564      
                     France    2017   359
                     Spain     2015   767   
                     Germany   2015   868      
                     France    2015   969")
        
        df2 <- fread("COUNTRY   GDP2016   GDP2017 GDP2015
        Spain      1111       999    444
                     Germany    2222       888    555  
                     France     3333       777    666")
        

        代码

        #first melt and modify df2
        df3 <- melt(df2, id.vars = "COUNTRY", variable.name = "YEAR")[, YEAR := as.numeric(gsub("[^0-9]", "", YEAR))]
        #then join
        df1[ df3, GDP := i.value, on = .(COUNTRY, YEAR) ][]
        
        #or use as oneliner
        df1[ melt(df2, id.vars = "COUNTRY", variable.name = "YEAR")[, YEAR := as.numeric(gsub("[^0-9]", "", YEAR))], GDP := i.value, on = .(COUNTRY, YEAR) ][]
        

        输出

        #    COUNTRY YEAR TRADE  GDP
        # 1:   Spain 2016   276 1111
        # 2: Germany 2016   323 2222
        # 3:  France 2016   392 3333
        # 4:   Spain 2017   456  999
        # 5: Germany 2017   564  888
        # 6:  France 2017   359  777
        # 7:   Spain 2015   767  444
        # 8: Germany 2015   868  555
        # 9:  France 2015   969  666
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多