【发布时间】:2020-03-09 15:34:33
【问题描述】:
library(tidyverse)
df <- tibble(col1 = c("A", "B", "C"),
col2 = c(NA, Inf, 5))
#> # A tibble: 3 x 2
#> col1 col2
#> <chr> <dbl>
#> 1 A NA
#> 2 B Inf
#> 3 C 5
我可以使用基本R is.na() 函数将NAs 轻松替换为0s,如下所示:
df %>% replace(is.na(.), 0)
#> # A tibble: 3 x 2
#> col1 col2
#> <chr> <dbl>
#> 1 A 0
#> 2 B Inf
#> 3 C 5
如果我尝试用is.infinite() 复制这个逻辑,事情就会中断:
df %>% replace(is.infinite(.), 1)
#> Error in is.infinite(.) : default method not implemented for type 'list'
看着这个older answer about Inf and R data frames,我可以拼凑出如下所示的解决方案。这将获取我的原始数据框并将所有NA 转换为0 并将所有Inf 转换为1。为什么is.infinite() 的行为不像is.na() 那样,(也许) 是什么更好的方式来做我想做的事?
df %>%
replace(is.na(.), 0) %>%
mutate_if(is.numeric, list(~na_if(abs(.), Inf))) %>% # line 3
replace(is.na(.), 1)
#> # A tibble: 3 x 2
#> col1 col2
#> <chr> <dbl>
#> 1 A 0
#> 2 B 1
#> 3 C 5
【问题讨论】:
-
如果您检查
?is.infinite-x - R object to be tested: the default methods handle atomic vectors.其中?is.na有matrix/data.frame/vector的方法。即x - an R object to be tested: the default method for is.na and anyNA handle atomic vectors, lists, pairlists, and NULL. -
你可以试试
df %>% mutate_if(is.numeric, replace_na, 0) %>% mutate_if(is.numeric, ~ replace(., is.infinite(.), 1)) -
你可以做
df %>% replace(sapply(., is.infinite), 1) -
谢谢,稍作修正,就是这样;
df %>% replace(is.na(.), 0) %>% replace(sapply(., is.infinite), 1).