使用replace_with_na函数将范围外的值替换为NA。

问题描述 投票:1回答:2

我有以下数据集

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)

但是,我试过的所有东西都没有用 有人知道为什么吗?先谢谢你! :)

r dataframe replace na data-cleaning
2个回答
2
投票

你应该提到你使用的包。从google上看,我猜测你使用的是 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

创建于2020-06-02 重读包 (v0.3.0)


3
投票

你可以用逻辑向量测试你的条件进行子集。

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
投票

你可以简单地使用 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))

2
投票

又是一个基础的R解决方案,这次是用函数 is.na<-

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)
  )

2
投票

我们可以用 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))
© www.soinside.com 2019 - 2024. All rights reserved.