2015-06-04 2 views
2

У меня есть две таблицы, таблица1 имеет столбец строк. Я хотел бы найти совпадения каждой строки в другой таблице, table2, но в соответствующем столбце table2 каждая ячейка содержит списки на запись в строке.Как сопоставить записи таблицы со списком записей в таблице в таблице R?

До сих пор я понял, как использовать grepl, чтобы соответствовать конкретной записи:

grepl(table1$label[i],table2$labels[[j]][k]) 

для некоторого I, J и K. я и J являются фиксированными, поскольку они являются количество строк в таблице 1 и таблице 2 соответственно, а к некоторое положительное значение, так что у меня что-то вроде этого:

for (i in 1:nrow(table1)){ 
    for (j in 1:nrow(table2){ 
    for(k ?){ 
    grepl(table1$label[i],table2$labels[[j]][k]) 
    } 
    } 
} 

я не совсем уверен, что поставить для k-цикла.

то, что я хотел бы сделать, как только я определил строки таблицы2, которые содержат строки таблицы1, должен сообщить соответствующие значения из другого столбца table2 и добавить их обратно в соответствующую строку строки в таблице1, поэтому i «Угадай, что мне понадобится еще несколько циклов ... есть ли ярлыки для нескольких проблем с реферированием, таких как это?

Некоторые примеры данных (обратите внимание, что также отсутствуют значения в TABLE2 списках, но я предполагаю, при совпадении их просто игнорируются, остальные элементы являются класс символов):

Таблица 1

label 
1 Tom  
2 Gemma  
3 Graham  

В таблице 2 (обновлена)

 item  labels 
1 Apple  Tom, ,John, ,Terry,  
2 Orange Bryan, ,Graham, 
3 Pear  Finn, ,Gemma, ,Graham, 

Выход

Вкладка ле 1

label item 
1 Tom  Apple 
2 Gemma Pear 
3 Graham Orange, Pear 

С помощью dput я

Table1 <- structure(list(label = c("Tom", "Gemma", "Graham")), .Names = "label", 
class = "data.frame", row.names = c(NA, 
-3L)) 


Table2 <- structure(list(item = c("Apple", "Orange", "Pear"), labels = list(
    structure(c("Tom", "", "John", "", "Terry", ""), .Dim = c(6L, 
    1L)), structure(c("Bryan", "", "Graham", ""), .Dim = c(4L, 
    1L)), structure(c("Finn", "", "Gemma", "", "Graham", ""), .Dim = c(6L, 
    1L)))), .Names = c("item", "labels"), row.names = c(NA, -3L 
), class = "data.frame") 

Добавление: в отношении моего первоначального использования grepl, некоторые из лейблов в Table2 имеют лишь частичное совпадение с ярлыком в таблице 1, но имена уникальны в таблице 1, поэтому я хотел бы применить соответствие метке Table1, например Graham (таблица 1), к Graham (таблица 2) и Graham Green (таблица 2), например.

Таблица 2 (version2)

 item  labels 
1 Apple  Tom, ,John, ,Terry,  
2 Orange Bryan, ,Graham, 
3 Pear  Finn, ,Gemma, ,Graham Green, 

Выход Таблица1 будет то же самое.

+0

Если вы хотите работать с решением, просьба указать примерные наборы данных и желаемый результат. –

+0

С данными, содержащими списки (например, «Таблица 2»), нам, вероятно, нужны сами данные, чтобы понять, как они отформатированы. Рассмотрим 'dput' или показывая код, используемый для создания таблицы. – Frank

+1

Спасибо @Frank, я никогда не использовал 'dput', очень полезный! – user1637359

ответ

4

Вот попытка использование data.table пакета

library(data.table) 
res <- setDT(Table2)[, list(label = unlist(labels)), by = item] 
setkey(res, label)[Table1, toString(unique(item)), by = .EACHI] 
#  label   item 
# 1: Tom  Apple 
# 2: Gemma   Pear 
# 3: Graham Orange, Pear 

То, что я в основном делал здесь, чтобы разделить labels в Table2 по каждому пункту.Тогда я агрегированный уникальные элементы на каждую метку при выполнении бинарного соединения слева обратно Table1


Edit для нового Table2 вы можете изменить код, чтобы

res <- setDT(Table2)[, list(label = unlist(labels)), by = item] 
Table1["item"] <- sapply(Table1$label, function(x) toString(unique(res[grepl(x, label), item]))) 
Table1 
# label   item 
# 1 Tom  Apple 
# 2 Gemma   Pear 
# 3 Graham Orange, Pear 
+0

Спасибо, Дэвид, я пробовал ваш код, но я не мог заставить его работать, возможно, это ввод данных - я предоставил 'dput' из таблиц в моем вопросе, чтобы уточнить. – user1637359

+0

См. Мое редактирование выше. –

+0

Привет, Дэвид, будет ли приведенный выше код необходимо отредактировать, если мои ярлыки в таблице 1 и 2 включают полные имена, такие как «Том Джонс» или дефисные имена, такие как «Джемма Остин-Давенпорт», а не просто «Том», например, или если есть любые другие специальные символы, такие как '/'? – user1637359

1

Вот qdapTools подход, который использует data.table в бэкэнд. Тип данных немного неоднозначен. dput было бы полезно здесь.

То, что я считаю, что ваши данные основаны на комментарий Н.А.

Table1 <- read.table(text=" label 
1 Tom  
2 Gemma  
3 Graham", header=TRUE) 


key <- list(
    Apple = c('Tom', NA, 'John', NA, 'Terry'), 
    Orange = c('Bryan', 'Graham'), 
    Pear = c('Finn', 'Gemma', NA, 'Graham') 
) 

Теперь для поиска значения:

library(qdapTools) 
Table1[["item"]] <- lapply(Table1[[1]], lookup, key) 

## label   item 
## 1 Tom  Apple 
## 2 Gemma   Pear 
## 3 Graham Orange, Pear 

Если у вас есть data.frame попробуйте:

key2 <- data.frame(x = names(key)) 
key2[["item"]] <- key 

Table1[["item2"]] <- lapply(Table1[[1]], lookup, setNames(as.list(key2[[2]]), key2[[1]])) 

Если столбец действительно свернутый/вставленный вектор:

key2 <- data.frame(x = names(key)) 
key2[["item"]] <- lapply(key, paste, collapse=", ") 
Table1[["item2"]] <- lapply(Table1[[1]], lookup, setNames(strsplit(as.character(key2[[2]]), "\\s*,\\s*"), key2[[1]])) 
+0

Спасибо Tyler, я предоставил 'dput' из таблиц выше, чтобы уточнить, я думаю, что ваш формат table1 всегда немного отличается от моего, но я буду идти с вашим кодом. Извинения за не предоставление более четких данных, я буду использовать 'dput' в будущем для обеспечения ввода данных. – user1637359