R 数据帧中两个逗号分隔因子之间的部分匹配

R 数据帧中两个逗号分隔因子之间的部分匹配,r,matching,partial,R,Matching,Partial,正如标题所建议的,我的目标是在至少有两个匹配元素的独立数据帧中对两个因子(使用逗号分隔的值)进行部分匹配 我有两个这样的数据帧: df1 结构(列表(ID=c(55153274738034156),值=c(“3000210057100121300451006510207100132005620024130261003210031”), "10026, 10051, 10010, 10302", "10004, 10133, 10103", "10009, 10035", "10003, 102

正如标题所建议的,我的目标是在至少有两个匹配元素的独立数据帧中对两个因子(使用逗号分隔的值)进行部分匹配

我有两个这样的数据帧:

df1

结构(列表(ID=c(55153274738034156),值=c(“3000210057100121300451006510207100132005620024130261003210031”),
"10026, 10051, 10010, 10302", "10004, 10133, 10103", "10009, 10035", 
"10003, 10202, 10319, 10421, 10025, 10033, 10045, 10036, 10049, 10055, 10062, 10069, 10083, 10086, 10089, 10090, 10099, 10100, 10102, 10103, 10112, 10114, 10120, 10125, 10126, 10128, 10144, 10148, 10149, 10150, 10158, 10159, 11330, 10035, 13508, 12003, 10124, 100266, 11302, 15305, 10240, 25024, 23003, 25204, 25343, 23058, 22007, 25278, 25204, 30117, 25346, 22324, 25325, 25133, 25229", 
“11002、11107、13340、10344”)),类别=c(“待决条件”,“待决条件”,
“data.frame”),row.names=c(NA,-6L))
df2
```r
结构(list)(ID=c(75412289214,48222),value=c(“3000210041100312002413026”),
"10026, 10040", "10004, 10133", "10023, 10025, 10314, 10143", 
"10001, 10125, 10126, 10128", 
“10012010344”)),类=c(“待定”,“待定”,“数据帧”
),row.names=c(NA,-6L))
如上所示:1)ID不符合顺序,我按“值”列对它们进行了排序,2)每行中的元素数量可能不同,3)列表中的元素可能无序4)原始数据帧很大,因此我认为可能存在多个匹配,因此我还想输出匹配计数

***请注意,这里我按“值”对数据集进行排序,因此看起来它们是逐行匹配的,但实际上,如果查看整个数据集,情况并非如此,目标实际上是逐项查找匹配项

如果任何两个列表至少有两个公共元素:例如df1中的ID55和df1中的ID75,则我希望生成的df返回dataframe的ID和匹配元素,返回类似于

ID\u 1 ID\u 2匹配元素匹配计数
75   55    30002,20024,13026   3
我尝试使用字符串拆分来生成变量值“list”,但这仍然无助于我的部分匹配


df1我正在使用嵌套的
map

library(stringr)
df1 <- structure(list(ID = c(55, 153, 274, 380, 34, 156), value = c("30002, 10057, 10012, 30045, 10065, 10207, 10013, 20056, 20024, 13026, 10032, 10031", 
                                                             "10026, 10051, 10010, 10302", "10004, 10133, 10103", "10009, 10035", 
                                                             "10003, 10202, 10319, 10421, 10025, 10033, 10045, 10036, 10049, 10055, 10062, 10069, 10083, 10086, 10089, 10090, 10099, 10100, 10102, 10103, 10112, 10114, 10120, 10125, 10126, 10128, 10144, 10148, 10149, 10150, 10158, 10159, 11330, 10035, 13508, 12003, 10124, 100266, 11302, 15305, 10240, 25024, 23003, 25204, 25343, 23058, 22007, 25278, 25204, 30117, 25346, 22324, 25325, 25133, 25229", 
                                                             "11002, 11107, 13340, 10344")), class = c("tbl_df", "tbl", 
                                                                                                       "data.frame"), row.names = c(NA, -6L))

df2 <- structure(list(ID1 = c(75, 412, 289, 214, 48, 222), value1 = c("30002, 10041, 10031, 20024, 13026", 
                                                             "10026, 10040", "10004, 10133", "10023, 10025, 10314, 10143", 
                                                             "10001, 10125, 10126, 10128", 
                                                             "10012, 10020, 10344")), class = c("tbl_df", "tbl", "data.frame"
                                                             ), row.names = c(NA, -6L))
#Change value column into a list of numeric values
df1 <-  df1 %>% mutate(x = map(value,function(x) (as.numeric(unlist(str_split(x,","))))))
df2 <-  df2 %>% mutate(x1 = map(value1,function(x) (as.numeric(unlist(str_split(x,","))))))

#Combine dataframes
df <- cbind(df1,df2)

Final_Data <- enframe(map(df$x,~ map(df$x1,~.y[.y %in% .x],.y = .x))) %>% unnest() %>%  
        mutate(ID_1 = rep(df$ID,each = 6),ID_2 = rep(df$ID1,times=6),
               Length = lengths(value) ) %>% filter(Length > 2 )
库(stringr)
df1(2)

我不太了解您的预期输出。似乎存在不一致/打字错误

  • 您说“例如,df1中的ID55和df1中的ID75-”,但在您的预期输出中
    ID2=55
    ID1=75
    。它不应该是
    ID_1=55
    (因为它来自
    df1
    )和
    ID_2=75
    (来自
    df2
  • 为什么您给出的示例输出中没有
    10031
    值<对于
    ID_1=55
    ID_2=75
    ,code>value=10031
  • 同时位于
    df1
    df2
    中 撇开矛盾不谈,这似乎是一个相当简单的
    内部连接

    library(tidyverse)
    inner_join(
        df1 %>% separate_rows(value),
        df2 %>% separate_rows(value),
        by = "value", suffix = c("_1", "_2")) %>%
        group_by(ID_1, ID_2) %>%
        summarise(value = toString(value))
    ## A tibble: 7 x 3
    ## Groups:   ID_1 [5]
    #   ID_1  ID_2 value
    #  <dbl> <dbl> <chr>
    #1    34    48 10125, 10126, 10128
    #2    34   214 10025
    #3    55    75 30002, 20024, 13026, 10031
    #4    55   222 10012
    #5   153   412 10026
    #6   156   222 10344
    #7   274   289 10004, 10133
    

    请使用
    dput
    ”如上所示输出数据帧:1)ID完全被置乱“我不确定我是否理解您所说的置乱是什么意思。我也不清楚第二个数据集中的
    “…”
    表示什么。您是否有只包含一组点的行?我支持上一位评论者的请求,即使用
    dput
    以可复制且明确的方式发布最小数据。如果不确定,请查看如何提供。Hi@django,欢迎使用Stack!正如其他人所提到的,如果您可以执行
    dput(df1)
    并将其发布在您的问题中(使用“编辑”选项),这将极大地帮助其他人尝试回答您的问题。尝试重新创建您的第一个数据帧时,我会从如下
    ID开始,如果您有一个大数据帧,并且只想发布一定数量的数据帧,那么您也可以使用
    head()
    。因此,要提供数据帧的前3行,您可以使用dput(head(df1,3))
    @RussThomas,它没有因子。我已经编辑了这个部分,谢谢你的建议!非常感谢你!我不知道内部连接可以工作:)是的,你是对的,结果有一些输入错误,但这就像一个charm@dangodango请把答案重击一下,然后把它写成answer@dangodango正如Omar Abd El Naser所建议的,请查看StackOverflow帮助中心关于的文章。谢谢!不过,事实证明运行for循环需要一些时间。但这也行!非常感谢你花时间写这篇文章this@dangodango如果你仍然感兴趣,我用map改变for循环:D
    inner_join(
        df1 %>% separate_rows(value),
        df2 %>% separate_rows(value),
        by = "value", suffix = c("_1", "_2")) %>%
        group_by(ID_1, ID_2) %>%
        filter(length(value) > 2) %>%
        summarise(
            matched_element = toString(value),
            match_count = length(value))
    ## A tibble: 2 x 4
    ## Groups:   ID_1 [2]
    #   ID_1  ID_2 matched_element            match_count
    #  <dbl> <dbl> <chr>                            <int>
    #1    34    48 10125, 10126, 10128                  3
    #2    55    75 30002, 20024, 13026, 10031           4