【发布时间】:2014-03-10 00:10:30
【问题描述】:
问题已根据原文进行了修改。
在阅读了这个有趣的discussion 之后,我想知道如何使用 dplyr 替换列中的 NA,例如在 Lahman 击球数据中:
Source: local data frame [96,600 x 3]
Groups: teamID
yearID teamID G_batting
1 2004 SFN 11
2 2006 CHN 43
3 2007 CHA 2
4 2008 BOS 5
5 2009 SEA 3
6 2010 SEA 4
7 2012 NYA NA
以下内容没有按我的预期工作
library(dplyr)
library(Lahman)
df <- Batting[ c("yearID", "teamID", "G_batting") ]
df <- group_by(df, teamID )
df$G_batting[is.na(df$G_batting)] <- mean(df$G_batting, na.rm = TRUE)
来源:本地数据框 [20 x 3] 组:yearID、teamID
yearID teamID G_batting
1 2004 SFN 11.00000
2 2006 CHN 43.00000
3 2007 CHA 2.00000
4 2008 BOS 5.00000
5 2009 SEA 3.00000
6 2010 SEA 4.00000
7 2012 NYA **49.07894**
> mean(Batting$G_battin, na.rm = TRUE)
[1] **49.07894**
事实上,它估算的是整体平均值,而不是组平均值。您将如何在 dplyr 链中执行此操作?使用基础 R 中的 transform 也确实 not 起作用,因为它估算了整体平均值而不是组平均值。这种方法也将数据转换为常规数据。一个框架。有没有更好的方法来做到这一点?
df %.%
group_by( yearID ) %.%
transform(G_batting = ifelse(is.na(G_batting),
mean(G_batting, na.rm = TRUE),
G_batting)
)
编辑:将transform 替换为mutate 会出现以下错误
Error in mutate_impl(.data, named_dots(...), environment()) :
INTEGER() can only be applied to a 'integer', not a 'double'
编辑:添加 as.integer 似乎可以解决错误,并且 确实 会产生预期的结果。另请参阅@eddi 的回答。
df %.%
group_by( teamID ) %.%
mutate(G_batting = ifelse(is.na(G_batting), as.integer(mean(G_batting, na.rm = TRUE)), G_batting))
Source: local data frame [96,600 x 3]
Groups: teamID
yearID teamID G_batting
1 2004 SFN 11
2 2006 CHN 43
3 2007 CHA 2
4 2008 BOS 5
5 2009 SEA 3
6 2010 SEA 4
7 2012 NYA 47
> mean_NYA <- mean(filter(df, teamID == "NYA")$G_batting, na.rm = TRUE)
> as.integer(mean_NYA)
[1] 47
编辑:跟进@Romain 的评论,我从 github 安装了 dplyr:
> head(df,10)
yearID teamID G_batting
1 2004 SFN 11
2 2006 CHN 43
3 2007 CHA 2
4 2008 BOS 5
5 2009 SEA 3
6 2010 SEA 4
7 2012 NYA NA
8 1954 ML1 122
9 1955 ML1 153
10 1956 ML1 153
> df %.%
+ group_by(teamID) %.%
+ mutate(G_batting = ifelse(is.na(G_batting), mean(G_batting, na.rm = TRUE), G_batting))
Source: local data frame [96,600 x 3]
Groups: teamID
yearID teamID G_batting
1 2004 SFN 0
2 2006 CHN 0
3 2007 CHA 0
4 2008 BOS 0
5 2009 SEA 0
6 2010 SEA 1074266112
7 2012 NYA 90693125
8 1954 ML1 122
9 1955 ML1 153
10 1956 ML1 153
.. ... ... ...
所以我没有得到错误(很好),但我得到了一个(看似)奇怪的结果。
【问题讨论】:
-
错误信息令人困惑,但问题的根源在于
ifelse的语义混乱。我添加了一个问题,以确保我考虑更多github.com/hadley/dplyr/issues/254 -
我无法使用 dplyr 的开发版本重现该错误。
-
谢谢哈德利。 @Romain,感谢您的建议。我从 hadley/dplyr 安装了 master 分支并得到了上面的结果。与您在问题 #254 中的结果不同