Wybieranie tylko kolumn numerycznych z ramki danych


189

Załóżmy, że masz plik data.frame taki jak ten:

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

Jak wybrałbyś tylko te kolumny w x, które są numeryczne?

Odpowiedzi:


289

EDYCJA: zaktualizowano, aby uniknąć użycia niewłaściwego doradztwa sapply.

Ponieważ ramka danych jest listą, możemy użyć funkcji zastosowania listy:

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

Następnie standardowe podzbiór

x[ , nums]

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

Dla bardziej idiomatycznego nowoczesnego R. poleciłbym teraz

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

Mniej kluczowania, mniej odzwierciedlające szczególne dziwactwa R, a także prostsze i solidniejsze w użyciu w bazach danych opartych na bazie danych:

dplyr::select_if(x, is.numeric)

10
x[nums]lub też x[sapply(x,is.numeric)]działa. I zawsze wracają data.frame. Porównaj x[1]vs x[,1]- po pierwsze data.frame, drugi to wektor. Jeśli chcesz zapobiec konwersji, musisz użyć x[, 1, drop=FALSE].
— Marek

W jakikolwiek sposób wybrać tylko ciągłe dane? Ta metoda zwraca ciągłą, jak również całkowitą.
— Opuszczony

Gdy nie ma kolumny numerycznej, pojawia się następujący błąd undefined columns selected. Jak tego uniknąć?
— Yohan Obadia,

@SoilSciGuy ciągłe dane powinny być jak liczby. Być może masz dane czynnikowe w postaci liczbowej? Powinieneś otworzyć nowe pytanie.
— Brandon Bertelsen

1
@YohanObadia Możesz tryCatch()sobie z tym poradzić. Proszę rozważyć otwarcie nowego pytania.
— Brandon Bertelsen

79

Funkcja pakietu dplyr select_if() jest eleganckim rozwiązaniem:

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

44

Filter() z pakietu podstawowego jest idealną funkcją dla tego przypadku użycia: po prostu musisz zakodować:

Filter(is.numeric, x)

Jest także znacznie szybszy niż select_if():

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

zwraca (na moim komputerze) medianę 60 mikrosekund dla Filteri 21 000 mikrosekund dla select_if(350x szybciej).


To rozwiązanie nie zawiedzie, gdy nie ma kolumn numerycznych. Czy są jakieś wady korzystania z niego?
— bli

Filtr dotyczy tylko wierszy ramki danych, a nie kolumn. Jako takie rozwiązanie nie dałoby poprawnego wyniku.
— Michael

4
@Michael nie myli Filtruj z pakietu podstawowego i filtruj z pakietu dplyr!
— Kevin Zarca

1
@bli Nie widzę żadnych wad korzystania z filtru. Jego wejściem jest obiekt data.frame i zwraca data.frame
— Kevin Zarca

Po prostu chichotam tutaj w celach informacyjnych: to, co tu Filter()nie działa, to zamiana, np. Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris)Nie zadziała.
— Mobeus Zoom


5

To alternatywny kod do innych odpowiedzi:

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

z data.table

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

3
Jest to raczej komentarz do wybranej odpowiedzi, niż odpowiedź unikalna.
— Brandon Bertelsen,

2
Kolumny mogą mieć więcej niż jedną klasę.
— Rich Scriven,


2

Biblioteka PCAmixdata ma funkcję splitmix, która dzieli ilościową (dane liczbowe) i jakościową (dane kategorialne) daną ramkę danych „YourDataframe”, jak pokazano poniżej:

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

Innym sposobem może być:

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

1
Cześć Ayushi, to prawdopodobnie zostało odrzucone, ponieważ jest to powtórzenie pierwszej odpowiedzi, ale ta metoda ma pewne zidentyfikowane problemy. Spójrz na komentarze w pierwszej odpowiedzi, zobaczysz, co mam na myśli.
— Brandon Bertelsen,

1

Jeśli masz wiele zmiennych czynnikowych, możesz użyć select_iffunkcji funtion. zainstaluj pakiety dplyr. Istnieje wiele funkcji oddzielających dane poprzez spełnienie warunku. możesz ustawić warunki.

Użyj w ten sposób.

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

2
Wygląda jak duplikat wcześniejszej odpowiedzi stackoverflow.com/a/40808873/170352
— Brandon Bertelsen

0

To nie odpowiada bezpośrednio na pytanie, ale może być bardzo przydatne, szczególnie jeśli potrzebujesz czegoś takiego jak wszystkie kolumny numeryczne z wyjątkiem kolumny id i zmiennej zależnej.

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))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.