Как объединить эти фреймы данных - PullRequest
0 голосов
/ 19 марта 2019

У меня есть два 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

С двумя ВВП я мог бы использовать:

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

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

Тем не менее, с 3 ВВП я должен использовать что-то другое. То, что я хочу получить:

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

Буду признателен за любую помощь!

Ответы [ 4 ]

0 голосов
/ 19 марта 2019

data.table

пример данных

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
0 голосов
/ 19 марта 2019

Вы можете сделать:

library(tidyverse)

df1 %>%
  left_join(df2 %>%
              gather(YEAR, GDP, -COUNTRY) %>%
              mutate(YEAR = as.integer(sub("GDP", "", YEAR))),
            by = c("COUNTRY", "YEAR"))
0 голосов
/ 19 марта 2019

Проблема в том, что 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
  )
0 голосов
/ 19 марта 2019

Вам нужно melt df2, чтобы поместить его в тот же формат, что и df1.Затем я создаю новый столбец YEAR с gsub, удалив часть строки «GDP» и сохранив только год.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...