替换R数据帧中的无限值[为什么is.infinite()的行为不像is.na()的行为]

时间:2019-11-13 19:00:43

标签: r dplyr tidyr

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

1 个答案:

答案 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