R entfernen Sie Objekte aus einer Liste mit if-else-Anweisung
Ich habe eine Liste von Daten-frames, und möchte zu entfernen, die mit weniger als 2 Zeilen aus mylist:
a<-data.frame(x=c(1:4),y=c("m", "n", "o", "p"))
b<-data.frame(x=c(2:6),y=c("q", "w", "e", "r", "t"))
c<-data.frame(x=c(6,7),y=c("j","k"),z=c("$","#"))
d<-data.frame(x="9",y="q",z="+")
mylist<-list(a,b,c,d)
for (i in length(mylist)){
if (nrow(mylist[[i]])<=2){
mylist<-mylist[-i]
}
else{
mylist<-myslit
}}
Aber es schien nur, um Daten zu entfernen.Rahmen d.... Daten-frame-c ist immer noch in "mylist" nach der Ausführung der for-Schleife.
- +1 um zu zeigen, was Sie bereits versucht, und bieten ein funktionierendes Beispiel.
InformationsquelleAutor lamushidi | 2013-04-23
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies können Sie leicht unter Verwendung eines gelten-Schleife:
Bemerken, dass ich mit negativen Indizierung, um Elemente zu entfernen, anstatt Sie Sie auswählen.
Filter
Funktion. (Siehe meine Antwort weiter unten.)Hinzufügen zu den anderen Antworten: das ist genau die Art von Sache, die höherer Ordnung
Filter
Funktion für:?Filter
. Sie können ganz nützlich sein.Können Sie nicht tun, diese Prozedur mit
for
weil die Indizes ändern. Mitfor
, nach dem entfernen der Linie 2, Sie wird prüfen, Zeile 3, aber Sie müssen prüfen, Linie 2 wieder (weil die Linie 2 nicht mehr die gleiche Zeile wie vorher). Ändern Sie es zurepeat
oderwhile
.Oder nutzen Sie einfach @Paul-Lösung... 😛
for
können auch verwendet werden, siehe meine AntwortPaulus hat eine Antwort schon, aber deine Fehler wurde nicht hingewiesen.
Dein code hat zwei Probleme. Erste, Sie brauchen, um zu liefern eine Reihe zu deinem loop:
bzw.
for (i in seq_along(Länge(mylist)))
Ohne diese, Ihre Initialisierung sah aus wie
for (i in 4)
nach der Auswertung, was bedeutet, dass nur eine iteration ausgeführt wurde, entfernen von element 4 und auch nicht auf der Suche alle vorherigen Elemente.Jedoch, wenn Sie das problem beheben, ein anderes taucht auf. Nämlich, Ihre Liste nicht mehr hat 4 Elemente nach entfernen von element 3. Es hat nur 3 Elemente, während Ihre
i
- index gehen wird, bis 4, was insubscript out of bounds
Fehler.Daher kann man nur raten, den Ansatz anwenden, wie beschrieben von @Paul.
Auch, im Gegensatz zu der Behauptung, andernfalls ist es möglich, um das gleiche zu erreichen mit
for
Schleife, nur Ihr Ansatz muss etwas anders sein:Hier wählen Sie die Liste Elemente, die größer sind als 2, und ordnen Sie eine neue Liste.
Sapply
werden mehr speedy aber.for
Schleife. Wennmylist
ist groß, Sie könnte preallocate es zunächst, spart viel Speicher und Zeit.(i in length(mylist))
und(i in 1:length(mylist))
. Ein häufiger Fehler habe ich oft gemacht.Für ein paar Besondere Fälle, die anderen oben genannten Methoden nicht funktionieren, obwohl
while
arbeiten konnte. Ich habe die Erfahrung gemacht, dass, wenn Sie Rcoster Ansatzwhile
ohne hinzufügen einer Auswertung der zurückgegebenen Liste, wäre es immer noch zurückgeben, die falsche Antwort-denn jedes mal, wenn die Bedingungi<=length(mylist)
habe ausgewertet, die Länge dermylist
ändern kann, aufgrund der Löschung dermylist[-i]
. Daher diewhile
Auswertung stoppen konnte, bevor es erreicht alle unerwünschten Elemente in der Liste.Beispielsweise in meinem Fall, ich wollte sicherstellen, dass die gesamte Länge der
mylist[[i]]<=4
. Die Liste ist sehr groß (2284879 Elemente, mit zu beginnen). Beim ersten mal lief ich diewhile
evaluation, das Programm beendet, bevor die allemylist[[i]]>4
da die Länge dermylist
wurde kleiner. Ich musstetable(lengths(mylist))
zu beurteilen, ob alle unerwünschten Listen entnommen wurden. Wenn nicht, dann führen Sie diewhile
loop wieder. Zum Glück dauerte es nur zwei Läufe. Aber ich dachte, es ist notwendig zu betonen, falls jemand anderes kam hier und versuchen, mit dieserwhile
Ansatz.PS.
for
Schleife kann verwendet werden, auch wenn einige der evaluation Hinzugefügt, um zu beurteilen, ob re-Lauf notwendig ist.