subset() 和 grepl() 使用 REGEX 过滤 R 中的数据帧

subset() with grepl() using REGEX for filtering a dataframe in R

我正在学习 R 并尝试使用带有正则表达式的 subset() 和 grepl() 来过滤数据帧。我创建了一个非常小的数据框来玩:

x   y   z   w
1   10  a   k
2   12  b   l
3   14  c   m
4   16  d   n
5   18  e   o

我的代码如下:

subset(df14, grepl('^c | [l - n]', c(df14$z , df14$w) ), grepl('[yz]', colnames(df14)) )

在我看来,第二个参数应该 return grepl() 找到的行的索引,以匹配具有名称的列中的模式:'z' 或 'w'。但是,情况并非如此(returns 是一个包含 y 和 z 列的空数据框)。

我希望 return 第 2、3、4 行,因为 'w' 列包含 [l-n] 正则表达式模式中指定的字母 l、m、n 以及列 z 和 w因为这些名称与 subset().

的第三个参数中的正则表达式 [yz] 匹配

(我怀疑它是在查找列名而不是列内容的匹配项,这正是我感兴趣的地方。)

显然,我对结果本身不感兴趣。这是一个了解功能如何工作的实验。所以,我正在寻找的是一种解释和一种更正特定代码的方法——而不是替代解决方案。

我们将不胜感激您的建议。

'^c | [l - n]' 搜索表达式在这些列中找不到任何内容。此外,更直观的方法是使用 [ , ] 进行此类子集化。参见 http://adv-r.had.co.nz/Subsetting.html

有各种各样的问题。

一个问题是模式中的额外空格。删除它们或使用 free-spacing 修饰符 (?x)perl = TRUE。无论哪种方式,您都必须去掉字符 class 中的空格。 [l-n] 匹配 "m" 而 [l - n] 不匹配,即使有 (?x)。您可以阅读更多关于 free-spacing 修饰符及其对字符内外的影响 classes here

另一个问题是,在您的第一个 grepl 中,您在长度为 10 的向量(字符向量?我们无法从示例中看出)中搜索。第 6 个位置的 TRUE 是什么是指 5 行 data.frame? return 5 行数据框的第 6 行没有意义。相反,您可以查看是否为列 "w" 或 (|) 列 "z" 找到了您的模式。在每一列中查找,而不是列的串联。

您的第二个 grepl 中存在另一个问题,"w" 与 [yz] 不匹配。如果要 select 名称包含 "w" 或 "z" 的列,一种方法是使用 [wz]:

不需要 ^ 锚点,因为您的所有字符串都包含一个字符,但无论如何我都会保留它:

subset(df14, 
       subset = grepl('^c|[l-n]', df14$z) | 
           grepl('^c|[l-n]', df14$w),
       select = grepl('[wz]', colnames(df14)))
#  z w
#2 b l
#3 c m
#4 d n

或者使用 free-spacing 模式修饰符和不同的模式([wz] vs w|z)第二个 grepl:

subset(df14, 
       subset = grepl('(?x)^c | [l-n]', df14$z, perl = TRUE) | 
           grepl('(?x)^c | [l-n]', df14$w, perl = TRUE),
       select = grepl('w|z', colnames(df14)))
#  z w
#2 b l
#3 c m
#4 d n