【问题标题】:Applying ifelse in multiple variables / columns for replacing 99 and 999 to NA在多个变量/列中应用 ifelse 以将 99 和 999 替换为 NA
【发布时间】:2021-12-31 16:46:39
【问题描述】:

我有一个数据框,其中包含一些列,其中 99 应被视为缺失值 (NA),而其他列中 999 是为此目的给出的值。

dat$variable1 <- ifelse(dat$variable1 == 99, NA, dat$variable1)
dat$variable2 <- ifelse(dat$variable2 == 99, NA, dat$variable2)
dat$variable3 <- ifelse(dat$variable3 == 99, NA, dat$variable3)
dat$variable4 <- ifelse(dat$variable4 == 99, NA, dat$variable4)
dat$variable5 <- ifelse(dat$variable5 == 999, NA, dat$variable5)
dat$variable6 <- ifelse(dat$variable6 == 999, NA, dat$variable6)
dat$variable7 <- ifelse(dat$variable7 == 999, NA, dat$variable7)

我想找到一种更好的方法来做到这一点,因为有时我们可以处理很多很多列。我不知道如何遍历应该为 NA 替换这些值的特定变量,而且我不知道有一个包可以帮助我解决这个问题(我是 R 的初学者)。

编辑: 我必须为我在问题中所犯的错误道歉。我首先发布了dat$variable1 &lt;- ifelse(dat$variable1 == 99, NA, dat$EC),在所有代码行中都保留了“dat$EC”。谢谢大家的回答。

【问题讨论】:

    标签: r if-statement lapply missing-data


    【解决方案1】:

    您可以尝试使用dplyr::across

    对于一个虚拟数据dat 定义如下

    dat <- data.frame(
      variable1 = c(1,2,3,4,5,6,99),
      variable2 = c(1,2,99,4,5,6,7),
      variable3 = c(1:7),
      variable4 = c(5:11),
      variable5 = c(1,2,3,4,5,6,999),
      variable6 = c(1,2,3,4,999,6,7),
      variable7 = c(1:7),
      EC = c(-1,-2,-3,-4,-5,-6,-7)
    )
    
      variable1 variable2 variable3 variable4 variable5 variable6 variable7 EC
    1         1         1         1         5         1         1         1 -1
    2         2         2         2         6         2         2         2 -2
    3         3        99         3         7         3         3         3 -3
    4         4         4         4         8         4         4         4 -4
    5         5         5         5         9         5       999         5 -5
    6         6         6         6        10         6         6         6 -6
    7        99         7         7        11       999         7         7 -7
    

    你可以试试这个方法。

    library(dplyr)
    dat %>%
      rowwise %>%
      mutate(across(variable1:variable4, ~ifelse(.x == 99, NA, EC)),
             across(variable5:variable7, ~ifelse(.x == 999, NA, EC)))
    
      variable1 variable2 variable3 variable4 variable5 variable6 variable7    EC
          <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl> <dbl>
    1        -1        -1        -1        -1        -1        -1        -1    -1
    2        -2        -2        -2        -2        -2        -2        -2    -2
    3        -3        NA        -3        -3        -3        -3        -3    -3
    4        -4        -4        -4        -4        -4        -4        -4    -4
    5        -5        -5        -5        -5        -5        NA        -5    -5
    6        -6        -6        -6        -6        -6        -6        -6    -6
    7        NA        -7        -7        -7        NA        -7        -7    -7
    

    如果你知道列索引,比如我的dat,从variable1variable41:4variable5variable75:7,只使用列索引会给你同样的结果结果。

    dat %>%
      rowwise %>%
      mutate(across(1:4, ~ifelse(.x == 99, NA, EC)),
             across(5:7, ~ifelse(.x == 999, NA, EC)))
    
      variable1 variable2 variable3 variable4 variable5 variable6 variable7    EC
          <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl> <dbl>
    1        -1        -1        -1        -1        -1        -1        -1    -1
    2        -2        -2        -2        -2        -2        -2        -2    -2
    3        -3        NA        -3        -3        -3        -3        -3    -3
    4        -4        -4        -4        -4        -4        -4        -4    -4
    5        -5        -5        -5        -5        -5        NA        -5    -5
    6        -6        -6        -6        -6        -6        -6        -6    -6
    7        NA        -7        -7        -7        NA        -7        -7    -7
    

    添加

    dat <- data.frame(
      variable1 = c(1,2,3,4,5,6,99),
      variable2 = c(1,2,99,4,5,6,7),
      variable3 = c(1:7),
      variable4 = c(5:10,999),
      variable5 = c(1,2,3,4,5,6,99),
      variable6 = c(1,2,3,4,999,6,7),
      variable7 = c(1:7),
      EC = c(-1,-2,-3,-4,-5,-6,-7)
    )
    
    dat %>%
      rowwise %>%
      mutate(across(c(variable1, variable2, variable3, variable5), ~ifelse(.x == 99, NA, EC)),
             across(c(variable4, variable6, variable7), ~ifelse(.x == 999, NA, EC)))
    
      variable1 variable2 variable3 variable4 variable5 variable6 variable7    EC
          <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl> <dbl>
    1        -1        -1        -1        -1        -1        -1        -1    -1
    2        -2        -2        -2        -2        -2        -2        -2    -2
    3        -3        NA        -3        -3        -3        -3        -3    -3
    4        -4        -4        -4        -4        -4        -4        -4    -4
    5        -5        -5        -5        -5        -5        NA        -5    -5
    6        -6        -6        -6        -6        -6        -6        -6    -6
    7        NA        -7        -7        NA        NA        -7        -7    -7
    

    【讨论】:

    • 如果列不连续怎么办?我的意思是,如果 var5 和 var7 应该有 99 作为 NA 并且 var1 和 var3 应该有 999 作为 NA?有没有办法用例如列列表替换var1:var4? (“var”在我的例子中是指“变量”)
    • @Allan 我添加了上面的代码。假设 variable4 有 999,variable5 有 99。然后只需手动指定它们,它就会起作用。
    【解决方案2】:

    如果 99 和 999 是您的数据框 dat 中缺失的唯一值,您可以:

    dat[dat == 999] <- NA
    dat[dat == 99] <- NA
    

    如果没有,您可以使用dplyr 中的na_if

    library(dplyr)
    dat_1 <- dat %>%
      mutate(across(c(variable1, variable2, variable3, variable4), na_if, 99),
             across(c(variable5, variable6, variable7), na_if, 999))
    dat_1
    

    【讨论】:

      【解决方案3】:

      考虑在列块上运行 ifelse,因为它适用于向量和矩阵:

      var_99 <- c("variable1", "variable2", "variable3", "variable4")
      var_999 <- c("variable5", "variable6", "variable7")
      
      dat[var_99] <- ifelse(dat[var_99] == 99, NA, dat$EC)
      dat[var_999] <- ifelse(dat[var_999] == 999, NA, dat$EC)
      

      对于多个变量替换,将no 参数强制转换为矩阵:

      dat[var_99] <- ifelse(dat[var_99] == 99, NA, as.matrix(dat[var_99]))
      dat[var_999] <- ifelse(dat[var_999] == 999, NA, as.matrix(dat[var_99]))
      

      【讨论】:

      • 嗨,@Parfait。不幸的是,它没有用。当我在我的数据上尝试它时,我收到一条警告消息:` var_99 dat[var_99] <- ifelse(dat[var_99] == 99, NA, dat[var_99]) Warning message: In "[&lt;-.data.frame"("tmp", var_99, value = list(c(4, 3, 3, 4, : provided 188 variables to replace 2 variables 尽管以下代码可以正常工作:dat$var1 &lt;- ifelse(dat$var1 == 99, NA, dat$var1)
      • 我看到您将原始帖子从单列 dat$EC 中删除。对于多个列,使用as.matrix 强制no 参数。见编辑。
      • 对不起,我的问题,@Parfait。但现在这正是我正在寻找的答案。简单高效。非常感谢。
      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 2020-03-24
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多