【问题标题】:Replace values outside range with NA using replace_with_na function使用 replace_with_na 函数将范围外的值替换为 NA
【发布时间】:2020-09-20 18:58:52
【问题描述】:

我有以下数据集

structure(list(a = c(2, 1, 9, 2, 9, 8), b = c(4, 5, 1, 9, 12, 
NA), c = c(50, 34, 77, 88, 33, 60)), class = "data.frame", row.names = c(NA, 
-6L))

  a  b  c
1 2  4 50
2 1  5 34
3 9  1 77
4 2  9 88
5 9 12 33
6 8 NA 60

从 b 列我只想要 4-9 之间的值。 c列在50-80之间。将范围外的值替换为 NA,导致

structure(list(a = c(2, 1, 9, 2, 9, 8), b = c(4, 5, NA, 9, NA, 
NA), c = c(50, NA, 77, NA, NA, 60)), class = "data.frame", row.names = c(NA, 
-6L))

  a  b  c
1 2  4 50
2 1  5 NA
3 9 NA 77
4 2  9 NA
5 9 NA NA
6 8 NA 60

我用 replace_with_na_at 函数尝试了几件事,这似乎是最合乎逻辑的:

test <- replace_with_na_at(data = test, .vars="c",
                          condition = ~.x < 2 & ~.x > 2)

但是,我尝试过的任何方法都不起作用。有人知道为什么吗?提前致谢! :)

【问题讨论】:

  • replace_with_na_at() 来自哪个包?您应该在可重现的示例中包含相关的库调用。

标签: r dataframe replace na data-cleaning


【解决方案1】:

您可以使用逻辑向量来测试您的条件。

x$b[x$b < 4 | x$b > 9] <- NA
x$c[x$c < 50 | x$c > 80] <- NA
x
#  a  b  c
#1 2  4 50
#2 1  5 NA
#3 9 NA 77
#4 2  9 NA
#5 9 NA NA
#6 8 NA 60

数据:

x <- structure(list(a = c(2, 1, 9, 2, 9, 8), b = c(4, 5, 1, 9, 12, 
NA), c = c(50, 34, 77, 88, 33, 60)), class = "data.frame", row.names = c(NA, 
-6L))

【讨论】:

    【解决方案2】:

    又一个基础 R 解决方案,这次是函数 is.na&lt;-

    is.na(test$b) <- with(test, b < 4 | b > 9)
    is.na(test$c) <- with(test, c < 50 | c > 80)
    

    一个带有管道的包naniar解决方案可以是

    library(naniar)
    library(magrittr)
    
    test %>%
      replace_with_na_at(
        .vars = 'b',
        condition = ~(.x < 4 | .x > 9)
      ) %>%
      replace_with_na_at(
        .vars = 'c',
        condition = ~(.x < 50 | .x > 80)
      )
    

    【讨论】:

      【解决方案3】:

      您应该提及您正在使用的软件包。从谷歌搜索,我猜你正在使用naniar。问题似乎是您没有正确指定条件,但以下应该可以工作:

      library(naniar)
      
      test <- structure(list(a = c(2, 1, 9, 2, 9, 8), 
                          b = c(4, 5, 1, 9, 12, NA),
                          c = c(50, 34, 77, 88, 33, 60)), 
                     class = "data.frame", 
                     row.names = c(NA, -6L)) 
      
      replace_with_na_at(test, "c", ~.x < 50 | .x > 80)
      #>   a  b  c
      #> 1 2  4 50
      #> 2 1  5 NA
      #> 3 9  1 77
      #> 4 2  9 NA
      #> 5 9 12 NA
      #> 6 8 NA 60
      

      由reprex package (v0.3.0) 于 2020 年 6 月 2 日创建

      【讨论】:

        【解决方案4】:

        您只需使用Map 将您的值替换为NA。

        dat[2:3] <- Map(function(x, y) {x[!x %in% y] <- NA;x}, dat[2:3], list(4:9, 50:80))
        dat
        #   a  b  c
        # 1 2  4 50
        # 2 1  5 NA
        # 3 9 NA 77
        # 4 2  9 NA
        # 5 9 NA NA
        # 6 8 NA 60
        

        数据:

        dat <- structure(list(a = c(2, 1, 9, 2, 9, 8), b = c(4, 5, 1, 9, 12, 
        NA), c = c(50, 34, 77, 88, 33, 60)), class = "data.frame", row.names = c(NA, 
        -6L))
        

        【讨论】:

          【解决方案5】:

          我们可以使用map2

          library(purrr)
          library(dplyr)
          df1[c('b', 'c')] <- map2(df1 %>% 
                 select(b, c), list(c(4, 9), c(50,80)), ~ 
                     replace(.x, .x < .y[1]|.x > .y[2], NA))
          

          【讨论】:

            猜你喜欢
            • 2021-10-24
            • 1970-01-01
            • 2021-01-02
            • 1970-01-01
            • 2022-06-20
            • 2022-12-15
            • 2018-09-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多