检测两个字符串向量之间的差异。

3
我有一个看起来像这样的数据框 data_frame
df <- data_frame(name = c('john','bill','amy'),
           name.2 = c('johhn','ball','ammy')) 
df
# A tibble: 3 x 2
   name name.2
  <chr>  <chr>
1  john  johhn
2  bill   ball
3   amy   ammy

我想新增一列,显示两个姓名列(.2)的差异。就像这样:
df %>% 
mutate(diff = c('h','a','m')) 
# A tibble: 3 x 3
   name name.2  diff
  <chr>  <chr> <chr>
1  john  johhn     h
2  bill   ball     a
3   amy   ammy     m

如果可能的话,我更喜欢找到一种使用 tidyversestringr 元素的解决方案,但无论如何我都会接受。

2个回答

7
使用基本的R语言,我们可以实现以下操作:
diffc=diag(attr(adist(df$name,df$name.2, counts = TRUE), "trafos"))
transform(df,diff=regmatches(name.2,regexpr("[^M]",diffc)))
  name name.2 diff
1 john  johhn    h
2 bill   ball    a
3  amy   ammy    m

解析:

计算df[,1]df[,2]之间的近似字符串距离。

  d=adist(df$name,df$name.2, counts = TRUE)

获取转换矩阵的对角线:

   e= diag(attr(d, "trafos"))

找出那些被删除、替换或插入的位置,即未维护的位置:

    f=regexpr("[^M]",e)

提取在指定位置的df[,2]的值:
     dat$diff==regmatches(name.2,f)

它完美地运行了。您介意解释一下正在发生什么吗?谢谢。 - elliot
我不介意。首先,它通过使用adist()计算字符向量之间的近似字符串距离。然后选择变换矩阵,即trafos。这是通过使用函数attr实现的,因为trafos是输出中的一个属性。然后取该对角线并将其与原始向量匹配。查看?adist。那可能会有所帮助。 - Onyambu

2
您可以使用vecsets库:
library(vecsets)
df$diff <- mapply(vsetdiff, strsplit(df$name.2, split = ""),
                            strsplit(df$name, split = ""))

df
#  name name.2 diff
#1 john  johhn    h
#2 bill   ball    a
#3  amy   ammy    m

注意,看起来你只想要name.2中不在name中的值,这就是为什么mapply的第一个参数是name.2strsplit的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接