我有一个包含以下结构的数据列的大型数据框:
Event Person_ID Person_name Current_Result
1 1 1 Greg 1
2 1 2 John 2
3 1 3 Tony 3
4 2 1 Greg 3
5 2 2 John 2
6 2 4 Johanna 1
7 3 1 Greg 2
8 3 4 Johanna 1
9 3 5 Lucy 3
10 3 6 Mike 4
我想要做的是在最后添加一列,我可以在下一个事件(事件+ 1)中获得结果,如果该人没有参加下一个事件,则添加NA,如下所示:
Event Person_ID Person_name Current_Result Next_Result
1 1 1 Greg 1 3
2 1 2 John 2 2
3 1 3 Tony 3 NA
4 2 1 Greg 3 2
5 2 2 John 2 NA
6 2 4 Johanna 1 1
7 3 1 Greg 2 ...
8 3 4 Johanna 1 ...
9 3 5 Lucy 3 ...
10 3 6 Mike 4 ...
...
表中的事件具有不同数量的参与者,并且未订购参与者。所以我需要某种函数来查找每一行是否在事件+ 1中有一个具有相同Person_ID的人并返回相应的Current_Result。
我已经设法使用for循环和子集,但由于表非常大,因此计算需要很长时间。我想知道是否有人知道如何更有效地做到这一点。
答案 0 :(得分:0)
假设您的data.frame是根据事件订购的:
aux1 <- split(df, df[,1])[-length(unique(df$Event))]
aux2 <- split(df, df[,1])[-1]
df$Next_Rresult <- c(as.vector(mapply(function(x, y) y$Current_Result[match(x$Person_ID, y$Person_ID)], aux1, aux2)), rep(NA, lapply(split(df, df[,1]), dim)[[length(unique(df$Event))]][1]))
df
Event Person_ID Person_name Current_Result Next_Rresult
1 1 1 Greg 1 3
2 1 2 John 2 2
3 1 3 Tony 3 NA
4 2 1 Greg 3 2
5 2 2 John 2 NA
6 2 4 Johanna 1 1
7 3 1 Greg 2 NA
8 3 4 Johanna 1 NA
9 3 5 Lucy 3 NA
10 3 6 Mike 4 NA
答案 1 :(得分:0)
我考虑扩展数据集以包含Event
和Person_ID
的所有组合,以便正确制作新列,从而解决了这个问题。我在最后删除了额外的行。
首先,我尝试使用expand
函数,如果需要安装,该函数位于 tidyr 包(devtools::install_github("hadley/tidyr")
)的开发版本中。这会扩展数据集以包括感兴趣的列的所有组合,然后您可以将其与原始数据集连接,以便为缺少的组合添加行。
我使用的其他功能,包括left_join
,来自 dplyr 。对于每个Person_ID
,使用mutate
和lead
计算下一个事件的值,然后使用filter
删除无关的行。
library(tidyr)
library(dplyr)
dat %>%
expand(Event, Person_ID) %>% # expand so have all combinations of Person_ID and Event
left_join(dat) %>% # use left join with original dataset, NA filled in
group_by(Person_ID) %>%
mutate(Next_Result = lead(Current_Result, order_by = Event)) %>%
filter(!is.na(Current_Result))
Source: local data frame [10 x 5]
Groups: Person_ID
Person_ID Person_name Event Current_Result Next_Result
1 1 Greg 1 1 3
2 2 John 1 2 2
3 3 Tony 1 3 NA
4 1 Greg 2 3 2
5 2 John 2 2 NA
6 4 Johanna 2 1 1
7 1 Greg 3 2 NA
8 4 Johanna 3 1 NA
9 5 Lucy 3 3 NA
10 6 Mike 3 4 NA
我还使用 tidyr 包中的spread
添加了缺少的组合,然后重新gather
将该数据集恢复为长格式。说实话,这似乎有点笨拙,但确实添加了Event
和Person_ID
的缺失组合。链的其余部分与以前相同。
dat %>%
spread(Event, Current_Result) %>% # spread adds in NA if missing combinations
gather(Event, Current_Result, 3:5) %>% # gather back to long format
group_by(Person_ID) %>%
mutate(Next_Result = lead(Current_Result, order_by = Event)) %>%
filter(!is.na(Current_Result))