首页 > 解决方案 > 比较列和运动差异的字符串

问题描述

我有一个数据框,其中包含这种格式的字符串等等。这是表格的样子:

x <- data.frame("v1_old" = c("[is_minimum] = '0'", "[is_minimum] = '0'"),
                "v1_new" = c("[is_minimum] = '0' and [is_minimum] = '1'", "[is_minimum] = '0' and [t_sheet] ='1'"))

现在我正在比较两列并发现每行字符串中的差异,然后能够创建一个带有后缀_diff含义差异的新列。

现在我尝试了第一个代码 CODE1:

df <- data.frame(x)
old_cols <- grep("old$", names(df), value = TRUE)
new_cols <- grep("new$", names(df), value = TRUE)

df[sub("new$", "diff", new_cols)] <- Map(stringr::str_remove, 
                                         df[new_cols], df[old_cols])

这是我使用此代码 RESULT1得到的结果

result <- data.frame("v1_old" = c("[is_minimum] = '0'", "[is_minimum] = '0'"),
                "v1_new" = c("[is_minimum] = '0' and [is_minimum] = '1'", "[is_minimum] = '0' and [t_sheet] ='1'"),
                "v1_diff" = c ("[is_minimum] = '0' and [is_minimum] = '1'", "[is_minimum] = '0' and [t_sheet] ='1'"))

这不是我期望的结果。我希望 diff 列只有在两列比较之间不存在的那部分。

现在我有了这段代码,它给了我正确的结果,但问题是我必须手动更改列名才能得到结果。它效率不高,我希望得到相同的结果,但会自动选择列。我的问题是如何自动化此代码以像第一个代码一样工作并给我相同的结果。这是代码和结果 CODE2

x$v1_diff<- mapply(function(x, y) paste(setdiff(y, x), collapse = '| '), strsplit(x$v1_old, '\\||, | | -| \\+'), strsplit(x$v1_new, '\\||, | | -| \\+'))

此代码的结果是: RESULT2

result2 <- data.frame("v1_old" = c("[is_minimum] = '0'", "[is_minimum] = '0'"),
                "v1_new" = c("[is_minimum] = '0' and [is_minimum] = '1'", "[is_minimum] = '0' and [t_sheet] ='1'"),
                "v1_diff" = c (" and| '1'", "and| [t_sheet]| ='1'"))

第二个结果是我所期望的,但是正如您在第二个代码中看到的那样,我必须手动更改列名,但第一个代码我没有。如何自动化第二个代码或将其更改为看起来像第一个代码但给出相同的输出?

标签: r

解决方案


一个想法是拆分并使用setdiff以查找不同的单词。用于paste将它们转换为字符串,即

i1 <- lapply(x, strsplit, ' ')
mapply(function(x, y)paste(setdiff(x, y), collapse = ' | '), i1[[2]], i1[[1]])

#[1] "and | '1'"              "and | [t_sheet] | ='1'"

然后,您可以将其分配回您的数据框,即

x$v2_diff <- mapply(function(x, y)paste(setdiff(x, y), collapse = ' | '), i1[[2]], i1[[1]])

推荐阅读