【问题标题】:Replace infinite values in an R data frame [why doesn't `is.infinite()` behave like `is.na()`]替换 R 数据框中的无限值 [为什么 `is.infinite()` 的行为不像 `is.na()`]
【发布时间】: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.namatrix/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 %&gt;% mutate_if(is.numeric, replace_na, 0) %&gt;% mutate_if(is.numeric, ~ replace(., is.infinite(.), 1))
  • 你可以做df %&gt;% replace(sapply(., is.infinite), 1)
  • 谢谢,稍作修正,就是这样; df %&gt;% replace(is.na(.), 0) %&gt;% replace(sapply(., is.infinite), 1).

标签: r dplyr tidyr


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2018-10-24
    • 2016-10-25
    • 1970-01-01
    • 2021-08-30
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    相关资源
    最近更新 更多