如何检测数据框单元格中的模式并使用 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,它显然只适用于整个字符串的命中。我对 stringrpkg 的 str_detect(x$A, " -") 比较幸运,它仍然不是最佳选择,因为我必须手动更改列名;但是 这会输出一个 TRUE/FALSE 命中列表,我不确定如何从这里继续?

在基础 R 中使用 sapplygrepl :

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