2016-08-01 9 views
1

Я пытаюсь сопоставить значения в 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), который дает мне правильную сумму, но не в том формате, который я хотел бы ниже:

Однако, я не думаю, что 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 
      } 
    } 
} 

Может ли кто-нибудь помочь?

Другой набор данных, который вызывает один, чтобы не быть кратным Отер:

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") 

ответ

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 

Update: Для того, чтобы заботиться о тех случаях, когда название двух списков не совпадают, мы можем петлю через 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 
+1

Я буду иметь дело со многими строками и хотел бы использовать data.table, если это возможно. Имеет ли data.table эквивалент вашего предложения? – user3067851

+0

Вы можете использовать 'as.data.table' для преобразования в' data.table'. – Psidom

+1

при использовании «match», который найдет соответствующие индексы, даже если имена столбцов не совпадают, правильно? Это может быть проблемой, если у меня есть соответствующее значение в столбцах с разными именами, нет? – user3067851