2017-07-10 2 views
3

Angenommen, ich habe die beiden folgenden Tabellen:prüfen, ob ein Element in einem Datenrahmen besteht in einem anderen Datenrahmen

Tabelle 1:

id word 
1  apple 
1  banana 
2  cherry 
2  donuts 
3  eggplant 
3  fish 

Table2 (KEY_WORDS):

key_words 
apple 
orange 
cherry 
peach 

I möchte prüfen, ob jedes Element in der 'Wort'-Spalte von Tabelle1 in Tabelle2 existiert und folgende Ergebnisse erhalten:

id apple orange cherry peach 
1  1  0  0  0 
2  0  0  1  0 
3  0  0  0  0 

Zum Beispiel
1 in der ersten Zeile und "Apfel" Spalte bedeutet ID 1 hat einen Apfel.
0 in der zweiten Zeile und "orange" Spalte bedeutet ID 2 hat keine Orange.

solches Ergebnis zu erhalten, schrieb ich eine for-Schleife:

data=list() 
data[[1]]=table1$id 
l=dim(table1)[1] 
for(i in 2:(length(key_words)+1)){ 
    exist=c() 
    for(j in 1:l){ 
    d1=table1[which(table1$id==data[[1]][j]),] 
    if(key_words[i] %in% d1$word){ 
     exist[j]=1 
    } else { 
     exist[j]=0 
    } 
    } 
    data[[i]]=exist 
} 
data=as.data.frame(data) 
names(data)=c("id","apple","orange","cherry","peach") 

Es funktioniert.

Wenn jedoch meine Tabelle Größe und Schlüsselwörter Zahl viel größer werden, zum Beispiel, wenn ich 10.000 IDs und 1.000 Schlüsselwörter habe, wird die FOR-Schleife für eine sehr lange Zeit ausgeführt.

Gibt es eine schnellere Methode, um die Laufzeit zu verringern?

Antwort

2
library(data.table) 

dat <- fread("id word 
1  apple 
      1  banana 
      2  cherry 
      2  donuts 
      3  eggplant 
      3  fish") 


dat_key <- fread("key_words 
apple 
orange 
cherry 
peach") 

dat_wide <- data.table(ID = unique(dat$id)) 
l <- lapply(dat_key$key_words, function(x) dat_wide[, (x) := ifelse(ID %in% dat[word == x]$id, 1, 0)][]) 

dat_wide 

    ID apple orange cherry peach 
1: 1  1  0  0  0 
2: 2  0  0  1  0 
3: 3  0  0  0  0 
+2

meine Lektüre der Q ist, dass es, dass zu prüfen ist Die key_words befinden sich im Hauptdatensatz, dh von Ihrer Antwort weg. (mein schrecklicher Versuch: dat [, lapply (key_words, "% in%", Wort), by = id]) – user20650

+2

Danke, ich schätze, ich habe es falsch gelesen. Aktualisiert, um die korrekte Ausgabe zu erhalten. –

1
data.frame(t(sapply(split(table1, table1$id), function(a) 
    colSums(sapply(table2$key_words, function(x) a$word %in% x)) > 0))) 
# apple orange cherry peach 
#1 TRUE FALSE FALSE FALSE 
#2 FALSE FALSE TRUE FALSE 
#3 FALSE FALSE FALSE FALSE 

Die Boolesche in numerischen in einem weiteren Schritt bei Bedarf

temp = data.frame(t(sapply(split(table1, table1$id), function(a) 
    colSums(sapply(table2$key_words, function(x) a$word %in% x)) > 0))) 
data.frame(sapply(temp, as.numeric), row.names = row.names(temp)) 
# apple orange cherry peach 
#1  1  0  0  0 
#2  0  0  1  0 
#3  0  0  0  0 

DATA geändert werden können

table1 = structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L), word = c("apple", 
"banana", "cherry", "donuts", "eggplant", "fish")), .Names = c("id", 
"word"), class = "data.frame", row.names = c(NA, -6L)) 

table2 = structure(list(key_words = c("apple", "orange", "cherry", "peach" 
)), .Names = "key_words", class = "data.frame", row.names = c(NA, 
-4L)) 
+1

Gute Arbeit! Vielen Dank! – Leonard

Verwandte Themen