Auswählen nur numerischer Spalten aus einem Datenrahmen


189

Angenommen, Sie haben einen data.frame wie folgt:

x <- data.frame(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])

Wie würden Sie nur die Spalten in x auswählen, die numerisch sind?

Antworten:


288

BEARBEITEN: aktualisiert, um die Verwendung von schlecht beratenen zu vermeiden sapply.

Da ein Datenrahmen eine Liste ist, können wir die Listenanwendungsfunktionen verwenden:

nums <- unlist(lapply(x, is.numeric))  

Dann Standard-Teilmenge

x[ , nums]

## don't use sapply, even though it's less code
## nums <- sapply(x, is.numeric)

Für ein idiomatischeres modernes R würde ich jetzt empfehlen

x[ , purrr::map_lgl(x, is.numeric)]

Weniger Codey, weniger Reflexion der besonderen Macken von R und unkomplizierter und robuster für Datenbank-Back-Ended-Tibbles:

dplyr::select_if(x, is.numeric)

10
x[nums]oder x[sapply(x,is.numeric)]funktioniert auch. Und sie kehren immer zurück data.frame. Vergleiche x[1]vs x[,1]- erstens ist data.frame, zweitens ist ein Vektor. Wenn man eine Konvertierung verhindern will, muss man verwenden x[, 1, drop=FALSE].
Marek

Gibt es eine Möglichkeit, nur fortlaufende Daten auszuwählen? Diese Methode gibt sowohl stetig als auch ganzzahlig zurück.
Verfallen

Wenn keine numerische Spalte vorhanden ist, tritt der folgende Fehler auf undefined columns selected. Wie vermeidest du das?
Yohan Obadia

@SoilSciGuy kontinuierliche Daten sollten as.numerisch sein. Vielleicht haben Sie Faktordaten in numerischer Form? Sie sollten eine neue Frage öffnen.
Brandon Bertelsen

1
@YohanObadia Sie können ein verwenden, tryCatch()um damit umzugehen. Bitte erwägen Sie, eine neue Frage zu öffnen.
Brandon Bertelsen

79

Die Funktion des dplyr-Pakets select_if(ist eine elegante Lösung:

library("dplyr")
select_if(x, is.numeric)

43

Filter() aus dem Basispaket ist die perfekte Funktion für diesen Anwendungsfall: Sie müssen einfach codieren:

Filter(is.numeric, x)

Es ist auch viel schneller als select_if():

library(microbenchmark)
microbenchmark(
    dplyr::select_if(mtcars, is.numeric),
    Filter(is.numeric, mtcars)
)

gibt (auf meinem Computer) einen Median von 60 Mikrosekunden für Filterund 21 000 Mikrosekunden für select_if(350x schneller) zurück.


Diese Lösung schlägt nicht fehl, wenn keine numerischen Spalten vorhanden sind. Gibt es irgendwelche Nachteile bei der Verwendung?
bli

Der Filter gilt nur für Zeilen eines Datenrahmens und nicht für Spalten. Daher würde diese Lösung nicht das richtige Ergebnis liefern.
Michael

4
@Michael verwechseln Sie nicht Filter aus dem Basispaket und Filter aus dem dplyr-Paket!
Kevin Zarca

1
@bli Ich sehe keinen Nachteil bei der Verwendung von Filter. Seine Eingabe ist ein data.frame-Objekt und es gibt einen data.frame zurück
Kevin Zarca

Hier nur als Referenz einschalten: Was Filter()hier nicht funktioniert, ist Ersetzen, z Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris). B. nicht.
Mobeus Zoom

8

Wenn Sie nur an Spaltennamen interessiert sind, verwenden Sie diese:

names(dplyr::select_if(train,is.numeric))

5

Dies ist ein alternativer Code zu anderen Antworten:

x[, sapply(x, class) == "numeric"]

mit einer data.table

x[, lapply(x, is.numeric) == TRUE, with = FALSE]

3
Dies ist eher ein Kommentar zur ausgewählten Antwort als eine eindeutige Antwort.
Brandon Bertelsen

2
Spalten können mehr als eine Klasse haben.
Rich Scriven


2

Die Bibliothek PCAmixdata verfügt über eine Funktion splitmix, die quantitative (numerische Daten) und qualitative (kategoriale Daten) eines bestimmten Datenrahmens "YourDataframe" wie unten gezeigt aufteilt:

install.packages("PCAmixdata")
library(PCAmixdata)
split <- splitmix(YourDataframe)
X1 <- split$X.quanti(Gives numerical columns in the dataset) 
X2 <- split$X.quali (Gives categorical columns in the dataset)

2

Ein anderer Weg könnte wie folgt sein:

#extracting numeric columns from iris datset
(iris[sapply(iris, is.numeric)])

1
Hallo Ayushi, dies wurde wahrscheinlich abgelehnt, weil es eine Wiederholung der ersten Antwort ist, aber diese Methode hat einige Probleme, die identifiziert wurden. Schauen Sie sich die Kommentare in der ersten Antwort an, Sie werden sehen, was ich meine.
Brandon Bertelsen

1

Wenn Sie viele Faktorvariablen haben, können Sie verwenden select_if . Installieren Sie die dplyr-Pakete. Es gibt viele Funktionen, die Daten trennen, indem sie eine Bedingung erfüllen. Sie können die Bedingungen festlegen.

Verwenden Sie so.

categorical<-select_if(df,is.factor)
str(categorical)

2
Sieht aus wie ein Duplikat dieser früheren Antwort stackoverflow.com/a/40808873/170352
Brandon Bertelsen

0

Dies beantwortet die Frage nicht direkt, kann jedoch sehr nützlich sein, insbesondere wenn Sie so etwas wie alle numerischen Spalten mit Ausnahme Ihrer ID-Spalte und der abhängigen Variablen möchten.

numeric_cols <- sapply(dataframe, is.numeric) %>% which %>% 
                   names %>% setdiff(., c("id_variable", "dep_var"))

dataframe %<>% dplyr::mutate_at(numeric_cols, function(x) your_function(x))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.