根据R中其他列中的值替换一列中第二次出现的字符串

时间:2018-05-14 12:42:36

标签: r regex string find-occurrences

以下是一个示例数据框:

a <- c("cat", "dog", "mouse")
b <- c("my cat is a tabby cat and is a friendly cat", "walk the dog", "the mouse is scared of the other mouse")
df <- data.frame(a,b)

我希望能够删除col b中col a中第二次出现的值。

这是我想要的输出:

a      b
cat    my cat is a tabby and is a friendly cat
dog    walk the dog
mouse  the mouse is scared of the other

我尝试了gsub和一些字符串函数的不同组合,但我甚至无法在col中删除第二个(也是第二个)字符串中出现的字符串湾我想我会问一些与this类似的东西,但我不熟悉Perl并且无法将其翻译成R.

谢谢!

4 个答案:

答案 0 :(得分:1)

构建正确的Regex需要一些工作。

P1 = paste(a, collapse="|")
PAT = paste0("((", P1, ").*?)(\\2)")

sub(PAT, "\\1", b, perl=TRUE)
[1] "my cat is a tabby  and is a friendly cat"
[2] "walk the dog"                            
[3] "the mouse is scared of the other "   

答案 1 :(得分:0)

你可以这样做......

library(stringr)
df$b <- str_replace(df$b, 
                    paste0("(.*?",df$a,".*?) ",df$a), 
                    "\\1")

df
      a                                       b
1   cat my cat is a tabby and is a friendly cat
2   dog                            walk the dog
3 mouse        the mouse is scared of the other

正则表达式在其中的某处找到第一个字符串df$a,后跟一个空格和另一个df$a。捕获组是第二次出现之前直到空格的文本(由(...)表示),整个文本(包括第二次出现)被捕获组\\1(具有删除第二个df$a及其前一个空格的效果。第二个df$a之后的任何内容都不会受到影响。

答案 2 :(得分:0)

我实际上找到了另一种解决方案,但对于其他正则表达式的初学者来说,虽然更长,但可能更清晰:

library(stringr)
# Replace first instance of col a in col b with "INTERIM" 
df$b <- str_replace(b, a, "INTERIM")

# Now that the original first instance of col a is re-labeled to "INTERIM", I can again replace the first instance of col a in col b, this time with an empty string
df$b <- str_replace(df$b, a, "")

# And I can re-replace the re-labeled "INTERIM" to the original string in col a
df$b <- str_replace(df$b, "INTERIM", a)

# Trim "double" whitespace
df$b <- str_replace(gsub("\\s+", " ", str_trim(df$b)), "B", "b")


df
a            b
cat          my cat is a tabby and is a friendly cat
dog          walk the dog
mouse        the mouse is scared of the other

答案 3 :(得分:0)

Base R,拆分应用组合解决方案:

# Split-apply-combine: 

data.frame(do.call("rbind", lapply(split(df, df$a), function(x){

        b <- paste(unique(unlist(strsplit(x$b, "\\s+"))), collapse = " ")

        return(data.frame(a = x$a, b = b))

      }

    )

  ), 

  stringsAsFactors = FALSE, row.names = NULL

)

数据:

df <- data.frame(a = c("cat", "dog", "mouse"),
                 b = c("my cat is a tabby cat and is a friendly cat", "walk the dog", "the mouse is scared of the other mouse"), 
                 stringsAsFactors = FALSE)