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()
轻松地将NA
替换为0
,如下所示:
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
答案 0 :(得分:3)
is.infinite
根据?is.infinite
期望输入'x'是原子向量
x-要测试的对象:默认方法处理原子向量。
?is.na
可以将矢量,矩阵,data.frame用作输入
要测试的R对象:is.na和anyNA的默认方法处理原子向量,列表,成对列表和NULL
此外,通过选中methods
methods('is.na')
#[1] is.na.data.frame is.na.data.table* is.na.numeric_version is.na.POSIXlt is.na.raster* is.na.vctrs_vctr*
methods('is.infinite') # only for vectors
#[1] is.infinite.vctrs_vctr*
我们可以将代码中的replace
修改为
library(dplyr)
df %>%
mutate_if(is.numeric, ~ replace_na(., 0) %>%
replace(., is.infinite(.), 1))
# A tibble: 3 x 2
# col1 col2
# <chr> <dbl>
#1 A 0
#2 B 1
#3 C 5