Слияние данных 2 переменных в R

Я пытаюсь объединить два набора данных. В прошлом я использовал merge() С by равно переменной, которую я хочу объединить. Однако теперь я хотел бы сделать это с двумя переменными. Мой первый набор данных выглядит примерно так:

Year   Winning_Tm    Losing_Tm
2011   Texas         Washington
2012   Alabama       South Carolina
2013   Tennessee     Texas

тогда у меня есть другой набор данных с рангом каждой команды (это очень упрощено) для каждого года. Вот так:

Year    Team             Rank
2011    Texas            32
2011    Washington       34
2012    South Carolina   45
2012    Alabama          12
2013    Texas            6
2013    Tennessee        51

Я хотел бы объединить их, чтобы у меня был набор данных, который выглядит так это:

Year   Winning_Tm    Winning_TM_rank    Losing_Tm        Losing_Tm_rank
2011   Texas         32                 Washington       34
2012   Alabama       12                 South Carolina   45
2013   Tennessee     51                 Texas            6

Я надеюсь, что есть простой способ сделать это, но это может быть сложнее. Спасибо!

4 ответов


два отдельных сливается. Вам нужно будет обернуть свой список by переменные c(), и поскольку переменные имеют разные названия, вам нужно by.x и by.y. После этого вы можете переименовать переменные ранга.

Я позвоню ваши данные winlose и teamrank, соответственно. Тогда вам понадобится:

first_merge <- merge(winlose, teamrank, by.x = c('Year', 'Winning_Tm'), by.y = c('Year', 'Team'))
second_merge <- merge(first_merge, teamrank, by.x = c('Year', 'Losing_Tm'), by.y = c('Year', 'Team'))

переименование переменных:

names(second_merge)[names(second_merge) == 'Rank.x'] <- 'Winning_Tm_rank'
names(second_merge)[names(second_merge) == 'Rank.y'] <- 'Losing_Tm_rank'

я воспроизвел ваши данные (попробуйте включить dput это в следующий раз):

A <- data.frame(
  Year = c(2011, 2012, 2013),
  Winning_Tm = c("Texas","Alabama","Tennessee"),
  Losing_Tm = c("Washington","South Carolina", "Texas"),
  stringsAsFactors = FALSE
)

B <- data.frame(
  Year = c("2011","2011","2012","2012","2013","2013"),
  Team = c("Texas","Washington","South Carolina","Alabama","Texas","Tennessee"),
  Rank = c(32,34,45,12,6,51),
  stringsAsFactors = FALSE
)

вы можете melt первый фрейм данных с использованием reshape2 пакет:

library(reshape2)

A <- melt(A, id.vars = "Year")
names(A)[3] <- "Team"

теперь это выглядит так:

> A
  Year   variable           Team
1 2011 Winning_Tm          Texas
2 2012 Winning_Tm        Alabama
3 2013 Winning_Tm      Tennessee
4 2011  Losing_Tm     Washington
5 2012  Losing_Tm South Carolina
6 2013  Losing_Tm          Texas

затем вы можете объединить наборы данных двух столбцов:

AB <- merge(A, B, by=c("Year","Team"))

выглядит так:

> AB
  Year           Team   variable Rank
1 2011          Texas Winning_Tm   32
2 2011     Washington  Losing_Tm   34
3 2012        Alabama Winning_Tm   12
4 2012 South Carolina  Losing_Tm   45
5 2013      Tennessee Winning_Tm   51
6 2013          Texas  Losing_Tm    6

затем с помощью


Если вы знакомы с SQL довольно сложный, но быстрый способ сделать все это за один шаг:

res <- sqldf("SELECT l.*,
                     max(case when l.Winning_Tm = r.Team then r.Rank else 0 end) as Winning_Tm_rank,
                     max(case when l.Losing_Tm = r.Team then r.Rank else 0 end) as Losing_Tm_rank
             FROM      df1 as l
             inner join df2 as r
             on        (l.Winning_Tm = r.Team
             OR        l.Losing_Tm = r.Team)
             AND       l.Year = r.Year
             group by  l.Year, l.Winning_Tm, l.Losing_Tm")

res
  Year Winning_Tm      Losing_Tm Winning_Tm_rank Losing_Tm_rank
1 2011      Texas     Washington              32             34
2 2012    Alabama South_Carolina              12             45
3 2013  Tennessee          Texas              51              6

данные:

df1 <- read.table(header=T,text="Year   Winning_Tm    Losing_Tm
2011   Texas         Washington
2012   Alabama       South_Carolina
2013   Tennessee     Texas")

df2<- read.table(header=T,text="Year Team Rank
2011    Texas            32
2011    Washington       34
2012    South_Carolina   45
2012    Alabama          12
2013    Texas            6
2013    Tennessee        51")

пусть X1 содержит вашу первую таблицу и X2 содержит вашу вторую таблицу.

library( dplyr )
library( plyr )

## Create a joint table to work with
XX <- inner_join( X1, X2, by="Year" )

## Compute the ranks
f <- function( x, y, r ) { r[ as.character(x) == as.character(y) ] }
rr <- ddply( XX, "Year", summarise,
  Winning_TM_Rank = f(Team, Winning_Tm, Rank ),
  Losing_TM_Rank = f(Team, Losing_Tm, Rank) )

## Combine the results and reorder the columns
inner_join( X1, rr )[,c(1,2,4,3,5)]