我尝试使用dplyr
和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
的文档说,&#34; group_by
函数采用现有的tbl并将其转换为分组的tbl在哪里进行操作&#34;按组&#34;。&#34;在这种情况下,组由id
变量确定,以下操作为fill(email)
。但是,它显然不是那样做的。
在任何人提出要求之前,如果字段都是character
而不是numeric
或factor
,则没有任何区别。
更新 @aosmith在Github上指出了this open issue。我要说的是,在问题得到解决之前,不能解决这个问题。其他一切都只是一种解决方法。所以,如果有人成功解决了这个问题,并将其发布在此处,我很乐意将其标记为解决方案。
答案 0 :(得分:10)
在 tidyr 的开发版本中已经修复了这个问题。现在,您可以使用来自tidyr_0.3.1.9000的fill
获得每个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
答案 1 :(得分:6)
幸运的是,您仍然可以使用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
答案 2 :(得分:2)
另一种选择是使用RecyclerView
中的DialogFragment
:
do
答案 3 :(得分:0)
有两个问题,是否重复,您是否必须使用dplyr
和tidyr
?
也许这可能是一个解决方案?
(
bar <- data.frame(id=c(1,1,2,2,3,3),
email=c('bob@email.com', NA, 'joe@email.com', NA, NA, NA))
)
#> id email
#> 1 bob@email.com
#> 1 <NA>
#> 2 joe@email.com
#> 2 <NA>
#> 3 <NA>
#> 3 <NA>
(
foo <- bar[!duplicated(bar$id),]
)
#> id email
#> 1 bob@email.com
#> 2 joe@email.com
#> 3 <NA>
答案 4 :(得分:0)
这有点难看,但它是使用dplyr
并使用您的示例数据的另一种选择
df %>%
group_by(id) %>%
mutate(email = email[ !is.na(email) ][1])
答案 5 :(得分:0)
我已经多次遇到这个问题了,我确实担心使用此问题。
df2 <- df %>% group_by(id) %>% fill(email)
在大型数据集上,因为我得出的结果好坏参半,发现以下解决方法。与map_df一起使用的split函数可确保您将所做的任何操作应用于每个ID的特定df,然后map_df像魔术一样重新绑定所有单个df。在许多其他情况下,它也被证明很方便。现在,这个问题已经过时了一些,已经解决了,但仍然是避免使用group_by()的有用替代方法。
df %>% split(.$id) %>% map_df(function(x){ x %>% fill(email)})