Ich habe eine Reihe von Spalten, die ich aus einem Datenrahmen entfernen möchte. Ich weiß, dass wir sie einzeln löschen können, indem wir Folgendes verwenden:
df$x <- NULL
Aber ich hatte gehofft, dies mit weniger Befehlen zu tun.
Außerdem weiß ich, dass ich Spalten mithilfe der Ganzzahlindizierung wie folgt löschen kann:
df <- df[ -c(1, 3:6, 12) ]
Ich befürchte jedoch, dass sich die relative Position meiner Variablen ändern könnte.
Angesichts der Stärke von R dachte ich, es könnte einen besseren Weg geben, als jede Spalte einzeln zu löschen.
df#drop(var_name)
ist und wir stattdessen diese komplizierten Workarounds durchführen müssen?Antworten:
Sie können eine einfache Liste von Namen verwenden:
Alternativ können Sie eine Liste der zu erhaltenden Personen erstellen und sie namentlich referenzieren:
BEARBEITEN:
drop
Wenn Sie das Argument der Indexierungsfunktion noch nicht kennen , können Sie Folgendes tun, wenn Sie eine Spalte als Datenrahmen beibehalten möchten:drop=TRUE
(oder nicht erwähnt) löscht unnötige Dimensionen und gibt daher einen Vektor mit den Werten der Spalte zurücky
.quelle
DF[,keeps]
stattdessen seinDF[keeps]
?Es gibt auch den
subset
Befehl, der nützlich ist, wenn Sie wissen, welche Spalten Sie möchten:AKTUALISIERT nach Kommentar von @hadley: Um die Spalten a, c zu löschen , können Sie Folgendes tun:
quelle
subset
Funktion hätte eine Option wie "allbut = FALSE", die die Auswahl "invertiert", wenn sie auf TRUE gesetzt ist, dh alle Spalten außer denen in derselect
Liste behält .df[c("a", "c")]
subset
Befehls, bei dem Sie keine Anführungszeichen um die Spaltennamen setzen müssen - ich denke, es macht mir nichts aus, ein paar zusätzliche Zeichen einzugeben, nur um das Zitieren von Namen zu vermeiden :)subset
in anderen Funktionen verwenden sollten.ist wahrscheinlich am einfachsten oder für mehrere Variablen:
Oder wenn Sie es mit
data.table
s zu tun haben (per Wie löscht man eine Spalte nach Namen in data.table? ):oder für mehrere Variablen
quelle
within(df, rm(x))
ist bei weitem die sauberste Lösung. Da dies möglich ist, erscheint jede andere Antwort um eine Größenordnung unnötig kompliziert.within(df, rm(x))
wird nicht funktionieren , wenn es doppelte Spalten mit den Namenx
indf
.df <- data.frame(x = 1, y = 2); names(df) <- c("x", "x"); within(df, rm(x))
kehrt zurückdata.frame(x = 2, x = 2)
.within()
die leistungsstark ist, aber auch NSE verwendet. Der Hinweis auf der Hilfeseite besagt deutlich, dass für die Programmierung ausreichende Sorgfalt angewendet werden sollte.Sie könnten so verwenden
%in%
:quelle
DF[ , !(names(DF) %in% drops)]
identical(post_time_1, post_time_2) [1] TRUE
= Dlist (NULL) funktioniert auch:
quelle
Wenn Sie die Spalten als Referenz entfernen und das damit verbundene interne Kopieren vermeiden möchten,
data.frames
können Sie dasdata.table
Paket und die Funktion verwenden:=
Sie können Zeichenvektornamen an die linke Seite des
:=
Operators undNULL
als RHS übergeben.Wenn Sie die Namen als Zeichenvektor außerhalb des Aufrufs an vordefinieren möchten
[
, wickeln Sie den Namen des Objekts in das aufrufende Objekt ein()
oder{}
erzwingen Sie, dass es im aufrufenden Bereich ausgewertet wird, nicht als Name im Bereich vonDT
.Sie können auch verwendet werden
set
, was den Aufwand für das vermeidet[.data.table
, und arbeitet auch fürdata.frames
!quelle
Es gibt eine potenziell leistungsfähigere Strategie, die auf der Tatsache basiert, dass grep () einen numerischen Vektor zurückgibt. Wenn Sie eine lange Liste von Variablen haben, wie ich es in einem meiner Datensätze tue, einige Variablen, die mit ".A" enden, und andere, die mit ".B" enden, und Sie möchten nur diejenigen, die mit ".A" enden (entlang Gehen Sie bei allen Variablen, die keinem der beiden Muster entsprechen, wie folgt vor:
Für den vorliegenden Fall ist es am Beispiel von Joris Meys möglicherweise nicht so kompakt, aber es wäre:
quelle
drops
in erster Linie als definierenpaste0("^", drop_cols, "$")
, wird dies viel schöner (lesen: kompakter) mitsapply
:DF[ , -sapply(drops, grep, names(DF))]
Eine andere
dplyr
Antwort. Wenn Ihre Variablen eine gemeinsame Namensstruktur haben, können Sie es versuchenstarts_with()
. Zum BeispielWenn Sie eine Folge von Variablen im Datenrahmen ablegen möchten, können Sie verwenden
:
. Zum Beispiel , wenn Sie fallen wolltevar2
,var3
und alle Variablen dazwischen, dann würden Sie nur mit gelassen werdenvar1
:quelle
select()
, wiecontains()
odermatches()
, die auch Regex akzeptieren.Andere Möglichkeit:
oder
quelle
setdiff
insbesondere bei einer sehr großen Anzahl von Spalten optimal ist.df <- df[ , -which(grepl('a|c', names(df)))]
Ausgabe:
Ausgabe:
quelle
Dplyr-Lösung
Ich bezweifle, dass dies hier unten viel Aufmerksamkeit erregt, aber wenn Sie eine Liste von Spalten haben, die Sie entfernen möchten, und Sie dies in einer
dplyr
Kette tun möchten, die ichone_of()
in derselect
Klausel verwende:Hier ist ein einfaches, reproduzierbares Beispiel:
Die Dokumentation finden Sie unter Ausführen
?one_of
oder hier:http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
quelle
Aus Interesse weist dies auf eine der seltsamen Mehrfachsyntaxinkonsistenzen von R hin. Zum Beispiel bei einem zweispaltigen Datenrahmen:
Dies ergibt einen Datenrahmen
aber das ergibt einen Vektor
Dies wird alles in erklärt,
?[
aber es ist nicht genau das erwartete Verhalten. Na zumindest nicht für mich ...quelle
Hier ist ein
dplyr
Weg, um es zu tun:Ich mag das, weil es intuitiv zu lesen und zu verstehen ist, ohne Anmerkungen zu machen, und robust gegenüber Spalten ist, die ihre Position innerhalb des Datenrahmens ändern. Es folgt auch der vektorisierten Redewendung, mit
-
der Elemente entfernt werden.quelle
%<>%
zu ersetzen, das vereinfacht werden könntedf %<>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)
dplyr
ist es möglicherweise einfacher, sie zu gruppieren und nur ein Minus zu setzen:df.cut <- df %>% select(-c(col.to.drop.1, col.to.drop.2, ..., col.to.drop.n))
Ich denke immer wieder, dass es eine bessere Redewendung geben muss, aber für die Subtraktion von Spalten nach Namen neige ich dazu, Folgendes zu tun:
quelle
df[,-match(c("e","f"),names(df))]
-
?dropNamed()
In Bernd BischlsBBmisc
Paket gibt es eine Funktion , die genau dies tut.Der Vorteil besteht darin, dass das Wiederholen des Datenrahmenarguments vermieden wird und sich somit zum Einleiten eignet
magrittr
(genau wie bei dendplyr
Ansätzen):quelle
Eine andere Lösung, wenn Sie @ hadley's oben nicht verwenden möchten: Wenn "COLUMN_NAME" der Name der Spalte ist, die Sie löschen möchten:
quelle
COLUMN_NAME
nicht indf
(überprüfen Sie sich :)df<-data.frame(a=1,b=2)
. (3)df[,names(df) != "COLUMN_NAME"]
ist einfacher und leidet nicht unter (2)Darüber hinaus
select(-one_of(drop_col_names))
in früheren Antworten zeigten, gibt es ein paar anderedplyr
Optionen für die Spalten fallen mit ,select()
dass beinhalten nicht alle spezifischen Spaltennamen definieren (mit der dplyr Beispieldaten für etwas Abwechslung in Spaltennamen starwars):Wenn Sie eine Spalte löschen müssen, die möglicherweise im Datenrahmen vorhanden ist oder nicht, wird hier eine leichte Wendung verwendet
select_if()
, die im Gegensatz zur Verwendungone_of()
keineUnknown columns:
Warnung auslöst, wenn der Spaltenname nicht vorhanden ist. In diesem Beispiel ist 'bad_column' keine Spalte im Datenrahmen:quelle
Geben Sie den Datenrahmen und eine Zeichenfolge mit durch Kommas getrennten Namen zum Entfernen an:
Verwendung :
quelle
Suchen Sie den Index der Spalten, mit denen Sie löschen möchten
which
. Geben Sie diesen Indizes ein negatives Vorzeichen (*-1
). Unterteilen Sie dann diese Werte, um sie aus dem Datenrahmen zu entfernen. Dies ist ein Beispiel.quelle
Wenn Sie einen großen
data.frame
und wenig Speicher haben[
. . . . oderrm
undwithin
um Spalten von adata.frame
zu entfernen , wiesubset
es derzeit (R 3.6.2) mit mehr Speicher ist - neben dem Hinweis des Handbuchs, interaktiv zu verwendensubset
.quelle