2015-06-04 68 views
2

我有兩個表,table1有一列字符串。我想查找另一個表table2中每個字符串的匹配項,但是在相應的table2列中,每個單元格包含每個行條目的列表。如何將表條目與R中第二個表的列表條目進行匹配?

到目前爲止,我已經想通了如何使用grepl以匹配特定的條目:

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

一些I,J和K。 i和j是固定的,因爲它們分別是表1和表2的行數,但k是一些積極的價值,所以我有這樣的事情:

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

我真的不知道要放什麼東西爲k循環。

我確定包含table1字符串的table2行後,我想要做的是從不同的table2列報告相應的值並將它們追加到table1中相應的字符串行,所以我猜測我將需要更多的循環......有沒有像這樣的多個引用問題的快捷方式?

一些示例數據(注意,也缺少在表2列出了值,但符合這些只是被忽略時,我假設,其他條目是字符類):

表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,一些表2中的標籤只有一個部分匹配的標籤在Table1中,但名稱在Table1中是唯一的,所以我想將Table1標籤(例如Graham(Table1))與Graham(表2)和Graham Green(表2)例如

表2(版本2)

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

輸出表1將是相同的。

+0

如果您需要工作解決方案,請提供示例數據集和所需輸出。 –

+0

對於包含列表的數據(如「表2」),我們可能需要數據本身來了解它的格式。考慮「輸入」或顯示用於製作表格的代碼。 – 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 

我基本上在這裏做的是Table2每每一個項目拆分labels的嘗試。然後,我已經聚集每次每個標籤的唯一項目,同時進行二值LEFT JOIN回Table1


編輯爲您的新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中的標籤包含像Tom Jones這樣的全名或像Gemma Austen-Davenport這樣的複數名字,而不是僅僅是Tom,或者如果有的話,是否需要編輯上面的代碼任何其他特殊字符像'/'? – user1637359

1

這裏有一個qdapTools在後端使用data.table的方法。你的數據類型有點模糊。 dput在這裏會很有幫助。

我相信你的數據是基於NA評論

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

相關問題