我有以下数据集
df <- data.frame(id = c(1,2,3), names = c( "Adam Jones, John David, Maddy Kones",
"Adam Smith, Maddy Kones, John David", "Maddy Kones, John Peterson, Adam Smith"))
即
我希望看到行&#34; John&#34;在&#34; Adam&#34;
之后所以我的输出将是
id names
1 Adam Jones, John David, Maddy Kones
我不知道如何使用正则表达式。到目前为止我试过这个
output <- df [grep("Adam" [^,]* "John", df$names),]
答案 0 :(得分:4)
这里的一个基本R方法是使用grepl
和一个合适的模式:
Adam\b[^,]*,\\s*John.*
这表示匹配Adam
后跟单词边界以及直到第一个逗号的任何内容,紧接着John
作为下一个术语。我们没有任何丑陋的边缘情况,因为如果约翰必须跟随亚当,这意味着总会有一个逗号分隔这两个名字。
<强>代码:强>
df[grepl("Adam\\b[^,]*,\\s*John.*", df$names), ]
答案 1 :(得分:3)
<强>更新强>
当没有“亚当”或“约翰”时,原始解决方案没有给出预期的答案。例如,对于此数据框
df
# id names
#1 1 Adam Jones, John David, Maddy Kones
#2 2 Adam Smith, Maddy Kones, John David
#3 3 Maddy Kones, John Peterson, Adam Smith
#4 4 Adam Smith, Ronak Shah
使用原始解决方案,我们将输出为
# id names
#1 1 Adam Jones, John David, Maddy Kones
#NA NA <NA>
要更正此问题,我们会添加isTRUE
函数的附加检查,该功能会忽略此类NA
并仅向我们提供TRUE
个元素
df[sapply(strsplit(df$names, ","), function(x)
isTRUE(grep("John", x) - grep("Adam", x) == 1)), ]
# id names
#1 1 Adam Jones, John David, Maddy Kones
原始答案
另一种选择是将所有names
分开到,
并使用grep
来检查“John”和“Adam”出现的位置,并选择它们之间的区别是1(如“约翰”跟随“亚当”)。
df[sapply(strsplit(df$names, ","), function(x)
grep("John", x) - grep("Adam", x)) == 1, ]
#id names
#1 1 Adam Jones, John David, Maddy Kones