如果找到特定字符,则用 NA 替换整个值
Replace whole value by NA if specific character is found
如果在当前值 f.e 中找到特定字符,我想用 NA 替换特定行中的值。如果值包含“<”(小于),则 f.e。 "<7.5" 我想用 NA 替换整个值。
示例:
Column A: 3, 4, 8, <5.6, 1, 3
Column B: 7, 4, <6, 1, <2.2, 8
应转换为:
Column A: 3, 4, 8, NA, 1, 3
Column B: 7, 4, NA, 1, NA, 8
我在此处 (https://dplyr.tidyverse.org/reference/na_if.html) 找到了带有 mutate 和 na_if() 的示例,但它需要匹配整个字符串,f.e.
y <- c("abc", "def", "", "ghi")
na_if(y, "def")
因此“def”将被 NA 取代。但是如果我使用
y <- c("abc", "def", "", "ghi")
na_if(y, "ef")
没有任何内容被替换。还有一个例子
library(dplyr)
data <- starwars
data %>%
select(name, eye_color) %>%
mutate(name = na_if(name, "Luke Skywalker")) %>%
mutate(eye_color = na_if(eye_color, "unknown")) -> dataedited
这段代码非常适合我,但还需要完全匹配,而不仅仅是字符串的一部分。 这样我就可以手动编辑每一列,也许有一种方法可以跨多个列执行此操作。如果 name 包含“sky”,或者 eye 包含“unkn”,我想将值转换为 NA。
谁能帮帮我?
谢谢!
na_if
不会在 y
中占用一个以上的元素。我们可以在 replace
中创建一个逻辑向量来替换 NA
中的值。对于多列,使用 across
library(dplyr)
data <- data %>%
mutate(across(c(name, eye_color),
~ replace(., . %in% c("Luke Skywalker", "unknown"), NA)))
对于部分匹配,请在 str_detect
或 grepl
中使用 regex
library(stringr)
data <- data %>%
mutate(across(c(name, eye_color),
~ replace(., str_detect(., "sky|unkn"), NA)))
只需将列转换为数字,非数字的组件将转换为 NA。这将生成警告,但它们可以被抑制。
或者在下面的第二种方法中检查是否有非数字非点并为那些使用 NA 然后转换为数字,在这种情况下首先不会有警告。
第三种方法是相同的,只是它假设要转换为 NA 的值都包含 <
.
第四种方法将任何以 < 开头的组件替换为 <,然后使用 na_if
。
x <- c(7, 4, "<6", 1, "<2.2", 8)
# 1
suppressWarnings(as.numeric(x))
## [1] 7 4 NA 1 NA 8
# 2
as.numeric(ifelse(grepl("[^0-9.]", x), NA, x))
## [1] 7 4 NA 1 NA 8
# 3
as.numeric(ifelse(grepl("<", x), NA, x))
## [1] 7 4 NA 1 NA 8
# 4
library(dplyr)
as.numeric(na_if(sub("<.*", "<", x), "<"))
## [1] 7 4 NA 1 NA 8
如果我们有多个值希望映射到 NA 或正则表达式模式,请像这样使用替换:
y <- head(letters)
# 5
replace(y, y %in% c("a", "c"), NA)
## [1] NA "b" NA "d" "e" "f"
# 6
replace(y, grepl("a|c", y), NA)
## [1] NA "b" NA "d" "e" "f"
我也发现 na_if()
不够灵活,所以我经常使用我自己的版本 na_predicate()
。它有两个参数:要编辑的向量,以及 returns TRUE
或 FALSE
.
的谓词函数
根据您的情况,您可以将它与 dplyr 的 across()
结合使用,以编辑多列。
library(dplyr)
library(stringr)
na_predicate <- function(x, fn) {
predicate <- rlang::as_function(fn)
x[predicate(x)] <- NA
x
}
# Example of a simple predicate function. By default, it's applied to the vector
# to change
is_even <- function(x) x %% 2 == 0
na_predicate(1:10, is_even)
#> [1] 1 NA 3 NA 5 NA 7 NA 9 NA
# But you can use the formula notation to make it apply to something else
# instead
na_predicate(c("a", "b", "c", "d"), ~ is_even(1:4))
#> [1] "a" NA "c" NA
# Applying it to starwars data. Here's the original:
original_data <- starwars %>%
select(name, eye_color, skin_color) %>%
head() %>%
print()
#> # A tibble: 6 x 3
#> name eye_color skin_color
#> <chr> <chr> <chr>
#> 1 Luke Skywalker blue fair
#> 2 C-3PO yellow gold
#> 3 R2-D2 red white, blue
#> 4 Darth Vader yellow white
#> 5 Leia Organa brown light
#> 6 Owen Lars blue light
# And here I'm using na_predicate() to turn any value in the name/eye_color
# columns that contains an "l" into NA:
original_data %>%
mutate(across(c(name, eye_color),
na_predicate, ~ str_detect(., "l")))
#> # A tibble: 6 x 3
#> name eye_color skin_color
#> <chr> <chr> <chr>
#> 1 <NA> <NA> fair
#> 2 C-3PO <NA> gold
#> 3 R2-D2 red white, blue
#> 4 Darth Vader <NA> white
#> 5 Leia Organa brown light
#> 6 Owen Lars <NA> light
由 reprex package (v2.0.1)
于 2021-11-09 创建
如果在当前值 f.e 中找到特定字符,我想用 NA 替换特定行中的值。如果值包含“<”(小于),则 f.e。 "<7.5" 我想用 NA 替换整个值。
示例:
Column A: 3, 4, 8, <5.6, 1, 3
Column B: 7, 4, <6, 1, <2.2, 8
应转换为:
Column A: 3, 4, 8, NA, 1, 3
Column B: 7, 4, NA, 1, NA, 8
我在此处 (https://dplyr.tidyverse.org/reference/na_if.html) 找到了带有 mutate 和 na_if() 的示例,但它需要匹配整个字符串,f.e.
y <- c("abc", "def", "", "ghi")
na_if(y, "def")
因此“def”将被 NA 取代。但是如果我使用
y <- c("abc", "def", "", "ghi")
na_if(y, "ef")
没有任何内容被替换。还有一个例子
library(dplyr)
data <- starwars
data %>%
select(name, eye_color) %>%
mutate(name = na_if(name, "Luke Skywalker")) %>%
mutate(eye_color = na_if(eye_color, "unknown")) -> dataedited
这段代码非常适合我,但还需要完全匹配,而不仅仅是字符串的一部分。 这样我就可以手动编辑每一列,也许有一种方法可以跨多个列执行此操作。如果 name 包含“sky”,或者 eye 包含“unkn”,我想将值转换为 NA。
谁能帮帮我?
谢谢!
na_if
不会在 y
中占用一个以上的元素。我们可以在 replace
中创建一个逻辑向量来替换 NA
中的值。对于多列,使用 across
library(dplyr)
data <- data %>%
mutate(across(c(name, eye_color),
~ replace(., . %in% c("Luke Skywalker", "unknown"), NA)))
对于部分匹配,请在 str_detect
或 grepl
regex
library(stringr)
data <- data %>%
mutate(across(c(name, eye_color),
~ replace(., str_detect(., "sky|unkn"), NA)))
只需将列转换为数字,非数字的组件将转换为 NA。这将生成警告,但它们可以被抑制。
或者在下面的第二种方法中检查是否有非数字非点并为那些使用 NA 然后转换为数字,在这种情况下首先不会有警告。
第三种方法是相同的,只是它假设要转换为 NA 的值都包含 <
.
第四种方法将任何以 < 开头的组件替换为 <,然后使用 na_if
。
x <- c(7, 4, "<6", 1, "<2.2", 8)
# 1
suppressWarnings(as.numeric(x))
## [1] 7 4 NA 1 NA 8
# 2
as.numeric(ifelse(grepl("[^0-9.]", x), NA, x))
## [1] 7 4 NA 1 NA 8
# 3
as.numeric(ifelse(grepl("<", x), NA, x))
## [1] 7 4 NA 1 NA 8
# 4
library(dplyr)
as.numeric(na_if(sub("<.*", "<", x), "<"))
## [1] 7 4 NA 1 NA 8
如果我们有多个值希望映射到 NA 或正则表达式模式,请像这样使用替换:
y <- head(letters)
# 5
replace(y, y %in% c("a", "c"), NA)
## [1] NA "b" NA "d" "e" "f"
# 6
replace(y, grepl("a|c", y), NA)
## [1] NA "b" NA "d" "e" "f"
我也发现 na_if()
不够灵活,所以我经常使用我自己的版本 na_predicate()
。它有两个参数:要编辑的向量,以及 returns TRUE
或 FALSE
.
根据您的情况,您可以将它与 dplyr 的 across()
结合使用,以编辑多列。
library(dplyr)
library(stringr)
na_predicate <- function(x, fn) {
predicate <- rlang::as_function(fn)
x[predicate(x)] <- NA
x
}
# Example of a simple predicate function. By default, it's applied to the vector
# to change
is_even <- function(x) x %% 2 == 0
na_predicate(1:10, is_even)
#> [1] 1 NA 3 NA 5 NA 7 NA 9 NA
# But you can use the formula notation to make it apply to something else
# instead
na_predicate(c("a", "b", "c", "d"), ~ is_even(1:4))
#> [1] "a" NA "c" NA
# Applying it to starwars data. Here's the original:
original_data <- starwars %>%
select(name, eye_color, skin_color) %>%
head() %>%
print()
#> # A tibble: 6 x 3
#> name eye_color skin_color
#> <chr> <chr> <chr>
#> 1 Luke Skywalker blue fair
#> 2 C-3PO yellow gold
#> 3 R2-D2 red white, blue
#> 4 Darth Vader yellow white
#> 5 Leia Organa brown light
#> 6 Owen Lars blue light
# And here I'm using na_predicate() to turn any value in the name/eye_color
# columns that contains an "l" into NA:
original_data %>%
mutate(across(c(name, eye_color),
na_predicate, ~ str_detect(., "l")))
#> # A tibble: 6 x 3
#> name eye_color skin_color
#> <chr> <chr> <chr>
#> 1 <NA> <NA> fair
#> 2 C-3PO <NA> gold
#> 3 R2-D2 red white, blue
#> 4 Darth Vader <NA> white
#> 5 Leia Organa brown light
#> 6 Owen Lars <NA> light
由 reprex package (v2.0.1)
于 2021-11-09 创建