group_by() 进入 fill() 未按预期工作
group_by() into fill() not working as expected
我正在尝试使用 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
的文档说,"The group_by
function takes an existing tbl and converts it into a grouped tbl where operations are performed "by group"。"本例中的分组是由id
变量决定的,下面的操作就是fill(email)
。但是,很明显它没有这样做。
在任何人问之前,如果字段都是 character
而不是 numeric
或 factor
.
没有区别
更新
@aosmith 在 Github 上指出 this open issue。我要说的是,在解决该问题之前,不会有适当的解决方案。其他一切都只是一种解决方法。因此,如果有人成功地通过 PR 解决了该问题并将其发布在这里,我很乐意将其标记为解决方案。
两个问题,是不是重复了,一定要用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>
幸运的是,您仍然可以为此使用 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
这有点难看,但它是另一个使用 dplyr
并使用您的示例数据的选项
df %>%
group_by(id) %>%
mutate(email = email[ !is.na(email) ][1])
另一种选择是使用 do
来自 dplyr
:
df3 <- df %>% group_by(id) %>% do(fill(.,email))
看起来这已在 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
这个问题我遇到过好几次了,我很担心这个问题..
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)})
我正在尝试使用 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
的文档说,"The group_by
function takes an existing tbl and converts it into a grouped tbl where operations are performed "by group"。"本例中的分组是由id
变量决定的,下面的操作就是fill(email)
。但是,很明显它没有这样做。
在任何人问之前,如果字段都是 character
而不是 numeric
或 factor
.
更新 @aosmith 在 Github 上指出 this open issue。我要说的是,在解决该问题之前,不会有适当的解决方案。其他一切都只是一种解决方法。因此,如果有人成功地通过 PR 解决了该问题并将其发布在这里,我很乐意将其标记为解决方案。
两个问题,是不是重复了,一定要用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>
幸运的是,您仍然可以为此使用 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
这有点难看,但它是另一个使用 dplyr
并使用您的示例数据的选项
df %>%
group_by(id) %>%
mutate(email = email[ !is.na(email) ][1])
另一种选择是使用 do
来自 dplyr
:
df3 <- df %>% group_by(id) %>% do(fill(.,email))
看起来这已在 tidyr 的开发版本中得到修复。您现在使用 fill
从 tidyr_0.3.1.9000.
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
这个问题我遇到过好几次了,我很担心这个问题..
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)})