计算两个字符串之间的匹配

Luc*_*rno 6 r

我有两个数据框:

df.1 <- data.frame(loc = c('A','B','C','C'), person = c(1,2,3,4), str = c("door / window / table", "window / table / toilet / vase ", "TV / remote / phone / window", "book / vase / car / chair"))
Run Code Online (Sandbox Code Playgroud)

从而,

  loc person                             str
1   A      1           door / window / table
2   B      2 window / table / toilet / vase 
3   C      3    TV / remote / phone / window
4   C      4       book / vase / car / chair
Run Code Online (Sandbox Code Playgroud)

和,

df.2 <- data.frame(loc = c('A','B','C'), str = c("book / chair / chair", " table / remote / vase ", "window"))
Run Code Online (Sandbox Code Playgroud)

这使,

  loc                     str
1   A    book / chair / car
2   B  table / remote / vase 
3   C                  window
Run Code Online (Sandbox Code Playgroud)

我想创建一个变量df.1$percentage,其计算元素的百分比df.1$str是在df.2$str 编辑由LOC,或:

  loc person                             str percentage
1   A      1           door / window / table       0.00
2   B      2 window / table / toilet / vase        0.50
3   C      3    TV / remote / phone / window       0.25
4   C      4       book / vase / car / chair       0.00
Run Code Online (Sandbox Code Playgroud)

(1有0/3,2有2/4的比赛,3有1/4,4有0/4)

谢谢!

edd*_*ddi 5

有人可能会想出一个更聪明的解决方案,但这里有一个简单的方法:

library(data.table)
dt1 = data.table(df.1, key = "loc") # set the key to match by loc
dt2 = data.table(df.2)

dt1[, percentage := dt1[dt2][, # merge
           # clean up spaces and convert to strings
           `:=`(str = gsub(" ", "", as.character(str)),
                str.1 = gsub(" ", "", as.character(str.1)))][,
           # calculate the percentage for each row
           lapply(1:.N, function(i) {
                tmp = strsplit(str, "/")[[i]];
                sum(tmp %in% strsplit(str.1, "/")[[i]])/length(tmp)
           })
   ]]

dt1
#   loc person                             str percentage
#1:   A      1           door / window / table          0
#2:   B      2 window / table / toilet / vase         0.5
#3:   C      3    TV / remote / phone / window       0.25
#4:   C      4       book / vase / car / chair          0
Run Code Online (Sandbox Code Playgroud)


flo*_*del 5

您可能知道, data.frame 列也可以包含列表(请参阅创建列是列表的 data.frame)。因此,您可以将您str的单词拆分为单词列表:

df.1 <- transform(df.1, words.1 = I(strsplit(as.character(str), " / ")))
df.2 <- transform(df.2, words.2 = I(strsplit(as.character(str), " / ")))
Run Code Online (Sandbox Code Playgroud)

然后合并您的数据:

m <- merge(df.1, df.2, by = "loc")
Run Code Online (Sandbox Code Playgroud)

并简单地使用mapply以下方法计算百分比:

transform(m, percentage = mapply(function(x, y) sum(x%in%y) / length(x),
                                 words.1, words.2))
Run Code Online (Sandbox Code Playgroud)