查找两个数据框列之间共享的字符串
Finding strings shared between two dataframe columns
我有一个包含两列分隔字符串的数据框:
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=", "))))))
导致错误:
Error in eval(substitute(expr), envir, enclos) :
wrong result size (2), expected 3 or 1
除了不 return 需要的字符串外,这似乎也 return 每行的相同大小的结果(通过将上面的 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=", "))))
但是收到错误:
Error in eval(substitute(expr), envir, enclos) :
not compatible with STRSXP
这让人怀疑数据框中的列表是否与 tidyverse
兼容,因此,我是否需要采用完全不同的方法。
任何关于如何解决在 R 中的两个数据框列之间共享字符串的问题的建议(以及任何关于如何处理数据框中的列表值的见解)将不胜感激。
此基本 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)
你可以试试:
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"
我有一个包含两列分隔字符串的数据框:
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=", "))))))
导致错误:
Error in eval(substitute(expr), envir, enclos) : wrong result size (2), expected 3 or 1
除了不 return 需要的字符串外,这似乎也 return 每行的相同大小的结果(通过将上面的 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=", "))))
但是收到错误:
Error in eval(substitute(expr), envir, enclos) : not compatible with STRSXP
这让人怀疑数据框中的列表是否与 tidyverse
兼容,因此,我是否需要采用完全不同的方法。
任何关于如何解决在 R 中的两个数据框列之间共享字符串的问题的建议(以及任何关于如何处理数据框中的列表值的见解)将不胜感激。
此基本 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)
你可以试试:
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"