首页 > 解决方案 > 替换 R 数据框中的无限值 [为什么 `is.infinite()` 的行为不像 `is.na()`]

问题描述

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

我可以使用基本的 Ris.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'

看看这个关于 Inf 和 R 数据帧的旧答案,我可以将下面显示的解决方案组合在一起。这需要我的原始数据框,然后全部NA变成. 为什么不表现得像什么(也许)是做我想做的更好的方法?0Inf1is.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

标签: rdplyrtidyr

解决方案


is.infinite期望输入'x'是原子向量,根据?is.infinite

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

推荐阅读