【问题标题】:short ifelse for specific use case, set vector elements to NA针对特定用例的短 ifelse,将向量元素设置为 NA
【发布时间】:2020-01-18 08:10:08
【问题描述】:

我使用 elseif 来清理现实世界数据库中存在输入错误的数据。

假设我想清理一个我知道在现实世界中不能超过 100 的 X 值,所以我只想将高于 100 的所有值转换为不包含在分析中的 NA 值。

所以我会这样做:

df$x <- ifelse(df$x > 100, NA, df$x)

这会将所有高于 100 的值变为 NA 并保留其他值

这感觉很麻烦,而且当我使用很长的真实变量名时代码不可读。

有没有更短的方法来做我想做的事情?

谢谢!

r 中有什么方法可以缩短这个豌豆

【问题讨论】:

  • ifelse 本身就是“if-else”的简写。我也没有看到可读性问题。如果你想要一个替代方案,可能会有很多(评估任何可用作三元运算符的东西),但 ifelse 最适合它的用例。
  • @chmod777 ifelse 不仅仅是if-else 的简写。前者是vectorized,后者不是。例如,参见this post。
  • 我知道ifelse 是if-else 的向量等价物,但我暗示的只是它比我之前评论的第一行中的 if-else 块短。跨度>

标签: r


【解决方案1】:

我知道的最简单的方法是使用函数is.na&lt;-。

is.na(df$x) <- df$x > 100

解释。

函数is.na&lt;-是文件中定义的通用函数
src/library/base/R/is.R as

`is.na<-` <- function(x, value) UseMethod("is.na<-")

文件中定义了一种方法,即默认方法。

`is.na<-.default` <- function(x, value)
{
    x[value] <- NA
    x
}

这是 S3 的方法分派机制在答案的代码行中调用的内容。另一种调用方式是函数形式。

`is.na<-`(df$x, df$x > 100)

【讨论】:

  • @AntonySamuelB 有两个is.na 函数。这个分配(因此箭头&lt;-)NA's 给由第二个参数索引的向量元素。在这种情况下,它是一个逻辑索引。它也可以是 x &lt;- 1:10; is.na(x) &lt;- c(2, 6, 9) 之类的东西,一个整数索引向量。
  • 这是一个不错的选择:)
【解决方案2】:

使用data.table

setDT(df) df[x > 100, x := NA]

如果要对多列应用该操作,

column.names <- names(df)[names(df) %in% column.names] for(i.col in column.names){ set(df, which(df[[i.col]] > 100), i.col, NA) }

【讨论】:

    【解决方案3】:

    试试这个答案会有所帮助。

    df <- data.frame('X'=c(1,2,3,4,NA,100,101,102))
    
    df$X <- as.numeric(df$X)
    
    df$X <- ifelse((is.na(df$X) | df$X >100),NA,df$X)
    

    【讨论】:

      【解决方案4】:

      然后您可以使用列索引而不是列名。

      col <- which(names(df) == 'x')
      df[[col]] <- df[[col]] * c(1, NA)[(df[[col]]  > 100) + 1]
      

      或者

      df[[col]] <- with(df, replace(df[[col]], df[[col]] > 100, NA))
      

      所以在这里你只使用一次列名。

      【讨论】:

        猜你喜欢
        • 2018-10-08
        • 2019-05-28
        • 2011-10-07
        • 2017-09-10
        • 2010-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多