gpt4 book ai didi

替换 dplyr 链中的 NA

转载 作者:行者123 更新时间:2023-12-01 23:35:07 28 4
gpt4 key购买 nike

问题已根据原始问题进行了编辑

读完这篇有趣的文章后discussion我想知道如何使用 dplyr 替换列中的 NA,例如 Lahman 击球数据:

Source: local data frame [96,600 x 3]
Groups: teamID

yearID teamID G
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") ]
df <- group_by(df, teamID )
df$G[is.na(df$G)] <- mean(df$G, na.rm = TRUE)

来源:本地数据框 [20 x 3]组:yearID、teamID

   yearID teamID         G
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不起作用,因为它估算的是整体平均值而不是组平均值。此方法还将数据转换为常规数据。一个框架。有更好的方法吗?

df %.% 
group_by( yearID ) %.%
transform(G = ifelse(is.na(G),
mean(G, na.rm = TRUE),
G)
)

编辑:用 mutate 替换 transform 会出现以下错误

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 = ifelse(is.na(G), as.integer(mean(G, na.rm = TRUE)), G))

Source: local data frame [96,600 x 3]
Groups: teamID

yearID teamID G
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, na.rm = TRUE)
> as.integer(mean_NYA)
[1] 47

编辑:根据 @Romain 的评论,我从 github 安装了 dplyr:

> head(df,10)
yearID teamID G
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 = ifelse(is.na(G), mean(G, na.rm = TRUE), G))
Source: local data frame [96,600 x 3]
Groups: teamID

yearID teamID G
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
.. ... ... ...

所以我没有收到错误(很好),但我得到了一个(看似)奇怪的结果。

最佳答案

您遇到的主要问题是 mean 返回 double 值,而 G 列是整数。因此,将平均值包装在 as.integer 中是可行的,或者我猜您需要将整个列转换为 numeric

也就是说,这里有几个 data.table 替代方案 - 我没有检查哪一个更快。

library(data.table)

# using ifelse
dt = data.table(a = 1:2, b = c(1,2,NA,NA,3,4,5,6,7,8))
dt[, b := ifelse(is.na(b), mean(b, na.rm = T), b), by = a]

# using a temporary column
dt = data.table(a = 1:2, b = c(1,2,NA,NA,3,4,5,6,7,8))
dt[, b.mean := mean(b, na.rm = T), by = a][is.na(b), b := b.mean][, b.mean := NULL]

这就是我理想中想做的事情(there is an FR 关于此):

# again, atm this is pure fantasy and will not work
dt[, b[is.na(b)] := mean(b, na.rm = T), by = a]
<小时/>

ifelsedplyr 版本是(如 OP 中所示):

dt %>% group_by(a) %>% mutate(b = ifelse(is.na(b), mean(b, na.rm = T), b))

我不确定如何在 dplyr 中的一行中实现第二个 data.table 想法。我也不确定如何阻止 dplyr 扰乱/排序数据(除了创建索引列)。

关于替换 dplyr 链中的 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21714867/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com