如何检测数据框单元格中的模式并使用 R 将它们转换为 NA?
How to detect pattern in cells of data frame and convert them to NA using R?
我有一个数据框(3,000 行和 30 列),其中许多单元格在包含值的同一单元格中包含文本错误消息。类似于我的数据框的虚拟数据:
set.seed(123)
x <- NULL
x$A <- runif(100, -1, 1)
x <- as.data.frame(x)
x$A[round(runif(50, 1, 100))] <- sapply(x$A, substring, 1, 6)
set.seed(223)
x$A[round(runif(40, 1, 100))] <- paste(x$A, "- Error text")
set.seed(323)
x$A[round(runif(20, 1, 100))] <- paste(x$A, "- Some error texts are longer")
# same for column B
x$B <- runif(100, -1, 1)
x$B[round(runif(30, 1, 100))] <- sapply(x$B, substring, 1, 5)
set.seed(423)
x$B[round(runif(30, 1, 100))] <- paste(x$B, "- Error text")
set.seed(553)
x$B[round(runif(60, 1, 100))] <- paste(x$B, "- Some error texts are longer")
我希望将包含错误文本的单元格变成 NA,如下所示:
A B
1 -0.424844959750772 -0.160817455966026
2 -0.172 NA
3 -0.1820461563766 NA
4 NA -0.10
5 0.880934568587691 NA
6 -0.908887001220137 NA
我使用了 x$A[x$A %in% c(" -")] <- NA
,它显然只适用于整个字符串的命中。我对 stringr
pkg 的 str_detect(x$A, " -")
比较幸运,它仍然不是最佳选择,因为我必须手动更改列名;但是 这会输出一个 TRUE/FALSE 命中列表,我不确定如何从这里继续?
在基础 R 中使用 sapply
和 grepl
:
x[sapply(x, grepl, pattern = ' -')] <- NA
然后您可能想要更改列的类型。
x <- type.convert(x)
要了解这是如何工作的,我们可以举一个较小的例子。
x <- data.frame(A = c('-0.4248', '-0.172', '-0.363 - Error text', '0.880'),
B = c('-0.160', '-0.63 - Some error texts are longer',
'-0.882 - Error text', '-0.10'))
x
# A B
#1 -0.4248 -0.160
#2 -0.172 -0.63 - Some error texts are longer
#3 -0.363 - Error text -0.882 - Error text
#4 0.880 -0.10
grepl
returns TRUE
它找到模式的地方。
sapply(x, grepl, pattern = ' -')
# A B
#[1,] FALSE FALSE
#[2,] FALSE TRUE
#[3,] TRUE TRUE
#[4,] FALSE FALSE
然后我们将这些 TRUE
值转换为 NA
。
x[sapply(x, grepl, pattern = ' -')] <- NA
x
# A B
#1 -0.4248 -0.160
#2 -0.172 <NA>
#3 <NA> <NA>
#4 0.880 -0.10
我有一个数据框(3,000 行和 30 列),其中许多单元格在包含值的同一单元格中包含文本错误消息。类似于我的数据框的虚拟数据:
set.seed(123)
x <- NULL
x$A <- runif(100, -1, 1)
x <- as.data.frame(x)
x$A[round(runif(50, 1, 100))] <- sapply(x$A, substring, 1, 6)
set.seed(223)
x$A[round(runif(40, 1, 100))] <- paste(x$A, "- Error text")
set.seed(323)
x$A[round(runif(20, 1, 100))] <- paste(x$A, "- Some error texts are longer")
# same for column B
x$B <- runif(100, -1, 1)
x$B[round(runif(30, 1, 100))] <- sapply(x$B, substring, 1, 5)
set.seed(423)
x$B[round(runif(30, 1, 100))] <- paste(x$B, "- Error text")
set.seed(553)
x$B[round(runif(60, 1, 100))] <- paste(x$B, "- Some error texts are longer")
我希望将包含错误文本的单元格变成 NA,如下所示:
A B
1 -0.424844959750772 -0.160817455966026
2 -0.172 NA
3 -0.1820461563766 NA
4 NA -0.10
5 0.880934568587691 NA
6 -0.908887001220137 NA
我使用了 x$A[x$A %in% c(" -")] <- NA
,它显然只适用于整个字符串的命中。我对 stringr
pkg 的 str_detect(x$A, " -")
比较幸运,它仍然不是最佳选择,因为我必须手动更改列名;但是 这会输出一个 TRUE/FALSE 命中列表,我不确定如何从这里继续?
在基础 R 中使用 sapply
和 grepl
:
x[sapply(x, grepl, pattern = ' -')] <- NA
然后您可能想要更改列的类型。
x <- type.convert(x)
要了解这是如何工作的,我们可以举一个较小的例子。
x <- data.frame(A = c('-0.4248', '-0.172', '-0.363 - Error text', '0.880'),
B = c('-0.160', '-0.63 - Some error texts are longer',
'-0.882 - Error text', '-0.10'))
x
# A B
#1 -0.4248 -0.160
#2 -0.172 -0.63 - Some error texts are longer
#3 -0.363 - Error text -0.882 - Error text
#4 0.880 -0.10
grepl
returns TRUE
它找到模式的地方。
sapply(x, grepl, pattern = ' -')
# A B
#[1,] FALSE FALSE
#[2,] FALSE TRUE
#[3,] TRUE TRUE
#[4,] FALSE FALSE
然后我们将这些 TRUE
值转换为 NA
。
x[sapply(x, grepl, pattern = ' -')] <- NA
x
# A B
#1 -0.4248 -0.160
#2 -0.172 <NA>
#3 <NA> <NA>
#4 0.880 -0.10