查找两个数据框列之间共享的字符串

时间:2017-02-17 16:00:12

标签: r list dataframe dplyr intersection

我有一个包含两列分隔字符串的数据框:

df <- data.frame('a'=c('a, b, c, d', 'a, c', 'b, d'), 'b'=c('a, d', 'a', 'a, d'))

           a      b
1 a, b, c, d   a, d
2       a, c      a
3       b, d   a, d

我想创建第三列以包含与前两列相交的字符串,例如:

           a      b      c
1 a, b, c, d   a, d   a, d
2       a, c      a      a
3       b, d   a, d      d

我尝试了很多方法,包括将字符串转换为列表并返回,但我似乎无法正确使用。

使用dplyr我首先尝试使用:

df <- df %>%
    mutate(c=paste(c(intersect(unlist(strsplit(a, split=", ")), unlist(strsplit(b, split=", "))))))

导致错误:

  

eval中的错误(替换(expr),envir,enclos):         错误的结果大小(2),预期3或1

除了不返回所需的字符串之外,这似乎也返回了每行相同大小的结果(通过将上面的mutate函数从paste更改为length来验证):

df %>%
    mutate(c=length(c(intersect(unlist(strsplit(a, split=", ")), unlist(strsplit(b, split=", "))))))

           a    b   c
1 a, b, c, d a, d   2
2       a, c    a   2
3       b, d a, d   2

这让我担心我的所有行结果都被合并到一个结果中并重复。

尝试简化我尝试在使用交叉函数之前将字符串转换为列表的事情:

df %>% mutate(a_list=list(unlist(strsplit(a, split=", "))))

但收到错误:

  

eval中的错误(替换(expr),envir,enclos):          与STRSXP不兼容

这让人怀疑数据框中的列表是否与tidyverse兼容,因此,如果我需要采用完全不同的方法。

关于如何解决在R中的两个数据框列之间共享字符串的问题的任何建议(以及如何处理数据框中的列表类似值的任何见解)都将非常感激。

2 个答案:

答案 0 :(得分:1)

此基本R方法将起作用:使用strsplit将变量拆分为列表,每个元素都是一个字符向量。 mapply函数获取列表并将以下操作应用于每个列表中位于相同位置的元素对。然后使用insersect查找重叠元素,使用折叠paste将这些元素粘贴在一起。

df$c <- mapply(function(x, y) paste(intersect(x, y), collapse=", "),
               strsplit(df$a, ", "), strsplit(df$b, ", "))

df
           a    b    c
1 a, b, c, d a, d a, d
2       a, c    a    a
3       b, d a, d    d

数据

df <- data.frame('a'=c('a, b, c, d', 'a, c', 'b, d'),
                 'b'=c('a, d', 'a', 'a, d'), stringsAsFactors=FALSE)

答案 1 :(得分:0)

您可以尝试:

library(stringr)
# go go through each row, extract the letters, search for duplicates and paste together
apply(df, 1, function(x){
  tmp <- str_trim(unlist(str_split(x,",")))
  paste(tmp[duplicated(tmp)],collapse=", ")
 })
[1] "a, d" "a"   "d"