匹配两个不等长度的列表

时间:2016-08-01 21:15:13

标签: r match mapply

我试图匹配2个列表中的值,只有列表之间的变量名称相同。我希望结果是一个列表,列出长列表的长度,填写总匹配数。

jac <- structure(list(s1 = "a", s2 = c("b", "c", "d"), s3 = 5), 
                 .Names = c("s1", "s2", "s3"))

larger <- structure(list(s1 = structure(c(1L, 1L, 1L), .Label = "a", class = "factor"), 
          s2 = structure(c(2L, 1L, 3L), .Label = c("b", "c", "d"), class = "factor"), 
          s3 = c(1, 2, 7)), .Names = c("s1", "s2", "s3"), row.names = c(NA, -3L), class = "data.frame")

我正在使用mapply(FUN = pmatch, jac, larger)这给了我一个正确的总数,但不是我想要的格式:

s1  s2  s3  s1result    s2result    s3result
a   c   1   1   2   NA
a   b   2   1   1   NA
a   c   7   1   3   NA

但是,我不认为pmatch会确保在任何情况下匹配名称,所以我写了一个我仍然遇到问题的函数:

prodMatch <- function(jac,larger){
      for(i in 1:nrow(larger)){
          if(names(jac)[i] %in% names(larger[i])){
               r[i] <- jac %in% larger[i]
               r
          }
     }
}

任何人都可以帮忙吗?

另一个数据集导致one不是ohter的倍数:

 larger2 <- 
    structure(list(s1 = structure(c(1L, 1L, 1L), class = "factor", .Label = "a"), 
        s2 = structure(c(1L, 1L, 1L), class = "factor", .Label = "c"), 
        s3 = c(1, 2, 7), s4 = c(8, 9, 10)), .Names = c("s1", "s2", 
    "s3", "s4"), row.names = c(NA, -3L), class = "data.frame")

1 个答案:

答案 0 :(得分:0)

mapply返回匹配索引的列表,您可以使用as.data.frame将其转换为数据框:

as.data.frame(mapply(match, jac, larger))
#   s1 s2 s3
# 1  1  2 NA
# 2  1  1 NA
# 3  1  3 NA

cbind larger的结果符合您的预期:

cbind(larger, 
      setNames(as.data.frame(mapply(match, jac, larger)), 
               paste(names(jac), "result", sep = "")))

#  s1 s2 s3 s1result s2result s3result
#1  a  c  1        1        2       NA
#2  a  b  2        1        1       NA
#3  a  d  7        1        3       NA

更新:为了处理两个列表的名称不匹配的情况,我们可以同时遍历larger及其名称并从jac中提取元素,如下所示:

as.data.frame(
    mapply(function(col, name) { 
        m <- match(jac[[name]], col)
        if(length(m) == 0) NA else m  # if the name doesn't exist in jac return NA as well
        }, larger, names(larger)))

#  s1 s2 s3
#1  1  2 NA
#2  1  1 NA
#3  1  3 NA