我正在尝试使用dplyr
和对一些格式不佳的数据执行Last Observation Carried Forward操作tidyr
.它没有像我期望的那样工作.
library(dplyr) library(tidyr) df <- data.frame(id=c(1,1,2,2,3,3), email=c('bob@email.com', NA, 'joe@email.com', NA, NA, NA)) df2 <- df %>% group_by(id) %>% fill(email)
这导致:
Source: local data frame [6 x 2] Groups: id [3] id email (dbl) (fctr) 1 1 bob@email.com 2 1 bob@email.com 3 2 joe@email.com 4 2 joe@email.com 5 3 joe@email.com 6 3 joe@email.com
我希望它是:
Source: local data frame [6 x 2] Groups: id [3] id email (dbl) (fctr) 1 1 bob@email.com 2 1 bob@email.com 3 2 joe@email.com 4 2 joe@email.com 5 3 NA 6 3 NA
我希望它成为后者的原因是因为group_by
文档说"该group_by
函数需要一个现有的tbl并将其转换为一个分组的tbl,其中操作是按组"执行的." 在这种情况下,组由id
变量确定,并且以下操作是fill(email)
.但是,显然不是这样做的.
在任何人要求之前,如果字段都是或者character
代替numeric
或者,则没有区别factor
.
更新 @aosmith 在Github上指出了这个未解决的问题.我要说的是,在问题得到解决之前,这个问题不会得到妥善解决.其他一切都只是一种解决方法.所以,如果有人成功解决了这个问题,并将其发布在此处,我很乐意将其标记为解决方案.
看起来这已经在tidyr的开发版中修复了.您现在可以使用fill
tidyr_0.3.1.9000 获得每个id的预期结果.
df %>% group_by(id) %>% fill(email) Source: local data frame [6 x 2] Groups: id [3] id email (dbl) (fctr) 1 1 bob@email.com 2 1 bob@email.com 3 2 joe@email.com 4 2 joe@email.com 5 3 NA 6 3 NA
幸运的是,你仍然可以zoo::na.locf
用于此:
df %>% group_by(id) %>% mutate(email = zoo::na.locf(email, na.rm = FALSE)) # Source: local data frame [6 x 2] # Groups: id [3] # # id email # (dbl) (fctr) # 1 1 bob@email.com # 2 1 bob@email.com # 3 2 joe@email.com # 4 2 joe@email.com # 5 3 NA # 6 3 NA