Слияние данных 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)]