用NA替换NaN

10

假设有以下数据表:

DT <- data.table(a=c(1,2,3,4,5,6),b=c(NaN,NaN,NaN,4,5,6),c=c(NaN,3,3,3,NaN,NaN))

我该如何将每列中的所有NaN值替换为NA?寻求一种简洁的方法来实现这一点,但我也想知道是否可以使用lapply来实现,就像我下面尝试的那样。

迄今为止,我的方法如下:

DT[,lapply(SD,function(x){x[is.nan(x)] := NA}),.SDcols=c("a","b","c")]  

我的代码的实际结果是:

Error in := (x [is.nan(x)],NA): 检查 is.data.table(DT)== TRUE。否则,:= 和 :=(...)仅在特定方式下用于 j 中一次。请参阅帮助文件“:=”。


1
请参考Matt Dowle在此处的答案:https://dev59.com/cmw05IYBdhLWcg3wcReu#7249454 您需要使用for(j in names(DT)) { set(DT, which(is.nan(DT[[j]])), j, NA) } - markus
@markus 谢谢,就是这样。我之前没看到这篇帖子,谢谢。似乎需要使用一个好老的for循环和set :) - User878239
1
很高兴它起作用了。set实际上非常快,所以不要被循环“蒙蔽”。 - markus
2个回答

20

你可以轻松使用dplyr的mutate_all函数完成它。

DT <- DT %>% mutate_all(~ifelse(is.nan(.), NA, .))
print(DT)
#a  b  c
# 1 NA NA
# 2 NA  3
# 3 NA  3
# 4  4  3
# 5  5 NA
# 6  6 NA

上述代码等同于

DT %>% mutate_all(function(x) ifelse(is.nan(x), NA, x))

以下是使用data.table语法的一种方法。我不确定是否有更简单的方法。

DT[, names(DT) := lapply(.SD, function(x) ifelse(is.nan(x), NA, x))]

编辑:如下评论中 Markus 发布的替代方法。

DT[, lapply(.SD, function(x) replace(x, is.nan(x), NA))]

1
谢谢,但那不是dplyr的语法吗?如果可能的话,我想坚持使用datatable只进行一次操作。 - User878239
我用data.table语法编辑了我的回复,提供了一种方法来完成它。我主要使用dplyr,所以我不确定是否有比我发布的方法更简单的使用data.table的方法。 - Dave Rosenman
谢谢,这种新的方法很好用,但我也想指出评论中 Markus 的解决方案。我会接受它,因为你付出了努力,并且它也很有效。 - User878239
1
@DavidRosenman 使用set的优点在于它可以通过引用进行替换(https://cran.r-project.org/web/packages/data.table/vignettes/datatable-reference-semantics.html)。使用您的解决方案需要执行“DT <- DT [,...]”操作。而且您可以避免使用ifelse函数,尝试使用replace函数代替:“DT <- DT[, lapply(.SD,function(x) replace(x, is.nan (x), NA))]”。最佳方案。 - markus
1
DT %>% mutate(across(everything(), ~ifelse(is.nan(.), NA, .))) is how you can do it with across() that superseded mutate_all() - Paul Schmidt
mutate_all方法将POSIXct值更改为整数。我无法解决lapply的方法,因为它们会出现“Error: object '.SD' not found.”的错误。有没有一种可行的方法可以替换NaNNANULL,而不改变数据类型? - MikeB

1
你想要像这样的东西:
DT[DT == "NaN"] <- NA

理想情况下,这应该找到所有的NaN并用NA替换它。如果有更好的方法,请告诉我!

希望这可以帮到你!


2
谢谢,但我的NaN不是字符,所以你的代码不起作用:Error in [.data.table(DT, DT == "NaN") : i是无效类型(矩阵) - User878239
3
此外,NaN与任何值(包括自身)都不相等。请参见is.nan进行正确的测试。否则,您的想法是正确的。 - Matthew Lundberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接