2016-07-29 17 views
1

Ich habe zwei Listen. Der erste hat Strings für jedes Element. Die zweite Liste hat einen Datenrahmen für jedes Element. Die Datenrahmen haben eine Spalte "Start" und ein weiteres "Ende", zusammen mit anderen Informationen.R substr auf zwei Listen

text<-'this is a long text. its not an email' 
text0<-'another piece of text' 
text1<-'last sentence of nonsense' 
all.text<-list(text,text0,text1) 
features1<-data.frame(start=c(1,3,5,7),end=c(2,5,9,12),type=c('na','person','person','location')) 
features2<-data.frame(start=c(1,3,5,7),end=c(2,5,9,12),type=c('na','person','person','location')) 
features3<-data.frame(start=c(7,8,10,12),end=c(9,9,11,15),type=c('na','person','person','location')) 
all.features<-list(features1,features2, features3) 

Ich hoffe, das erste Textelement und den ersten Datenrahmen zu durchlaufen. Der Anfang und das Ende der Spalten des Datenrahmens können innerhalb von substr verwendet werden, um den Text zu extrahieren.

Für ein einzelnes Textelement kann ich die Schleife unten verwenden und sie dann zum Feature-Datenrahmen hinzufügen.

one.text<-NULL 
for (i in 1:nrow(features1)) one.text[i]<-((substr(text,features1[i,1],features1[i,2]))) 
features1$word<-one.text 

Allerdings kann ich keine Möglichkeit finden, eine Schleife zu verwenden oder zu verschachteln. Offensichtlich möchte ich keine Schleife verwenden, wenn es möglich ist, weil ich gelesen habe, dass sie ineffizient sind. Einige der Dinge, die ich versucht habe:

named.get<-function(text.list,features.list){ 
    named.entities<-substr(text.list,features.list[,1],features.list[,2]) 
} 
all<-sapply(all.text,named.get,all.features) 

Oder eine verschachtelte Schleife

one.obj<-NULL 
two.obj<-NULL 
for(i in 1:length(all.text)){ 
    for (j in 1:length(all.features)){ 
    one.obj[j]<-list([i]<-((substr(all.text[i],all.features[[i]][j,1],all.features[[i]][j,2])))) 
    } 
} 

Aber das hat nicht funktioniert. Ich habe die Subvignette gelesen, mehrere Stack-Overflow-Fragen gelesen und finde damit scheinbar keinen Weg.

Das Ziel ist es, eine Feature-Liste mit den extrahierten Termen zu bekommen, wie bei der obigen Schleife. Danke für jede Hilfe.

Antwort

1

Das Äquivalent einer Double-for-Loop ist die Verwendung von Map, wobei beide Listen als Argumente übergeben werden. Dann können Sie die Tatsache nutzen, dass substring vektorisiert ist, um die endgültige Extraktion durchzuführen.

Map(function(tex,fea) substring(tex, fea$start, fea$end), all.text, all.features) 
#[[1]] 
#[1] "th"  "is " " is a" "s a lo" 
# 
#[[2]] 
#[1] "an"  "oth" "her p" "r piec" 
# 
#[[3]] 
#[1] "ent" "nt" "en" "ce o" 
+0

Für meine eigene Neugier, ist es möglich, diese Ausgaben zu den entsprechenden Standorten hinzuzufügen? Ich meine, können wir '# [1]" th "" is "" a "" s a lo "' zu 'all.features [[1]]' und ähnlich für andere hinzufügen. – user2100721

+1

@ user2100721 ​​- sicher - so etwas wie 'Map (Funktion (tex, fea) cbind (fea, String = Teilstring (tex, fea $ start, fea $ end)), all.text, all.features)' – thelatemail

+0

ausgezeichnet! Vielen Dank. – user1370741