Wybieranie tylko kolumn numerycznych z ramki danych

Załóżmy, że masz dane.frame like this:

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

Jak wybrać tylko te kolumny w x, które są liczbowe?

 197
r
Author: Brandon Bertelsen, 2011-05-02

12 answers

EDIT: updated to avoid of ill-added sapply.

Ponieważ ramka danych jest listą, możemy użyć funkcji list-apply:

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

Następnie standardowy podzbiór

x[ , nums]

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

Dla bardziej idiomatycznego nowoczesnego R Polecam

x[ , purrr::map_lgl(x, is.numeric)]
W przeciwieństwie do innych języków, w których R jest językiem ojczystym, R jest językiem ojczystym, a R jest językiem ojczystym dla 2,5%, angielski dla 3,5% mieszkańców (2011).]}
dplyr::select_if(x, is.numeric)

Nowsze wersje dplyr obsługują również następującą składnię:

x %>% dplyr::select(where(is.numeric))
 306
Author: mdsumner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-17 20:18:06

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

library("dplyr")
select_if(x, is.numeric)
 82
Author: Sharon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-25 16:08:16

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

Filter(is.numeric, x)

Jest również 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 Filter i 21 000 mikrosekund dla select_if (350x szybciej).

 46
Author: Kevin Zarca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-02 09:13:24

Jeśli interesują Cię tylko nazwy kolumn, użyj tego:

names(dplyr::select_if(train,is.numeric))
 9
Author: user3065757,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 09:44:54

To alternatywny kod dla innych odpowiedzi:

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

Z data.table

x[, lapply(x, is.numeric) == TRUE, with = FALSE]
 6
Author: Enrique Pérez Herrero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-13 19:54:45
library(purrr)
x <- x %>% keep(is.numeric)
 3
Author: Yash Khokale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-23 18:28:22
iris %>% dplyr::select(where(is.numeric)) #as per most recent updates

Inną opcją z purrr byłoby negowanie discard Funkcji:

iris %>% purrr::discard(~!is.numeric(.))

Jeśli chcesz nazwy kolumn numerycznych, możesz dodać names lub colnames:

iris %>% purrr::discard(~!is.numeric(.)) %>% names
 3
Author: AlexB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-20 09:38:54

Biblioteka PCAmixdata ma functon splitmix, który dzieli ilościowe (dane liczbowe) i jakościowe (dane kategoryczne) danej ramki 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
Author: user1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 15:48:57

Inny sposób może być następujący: -

#extracting numeric columns from iris datset
(iris[sapply(iris, is.numeric)])
 2
Author: Ayushi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-09 07:04:22

Jeśli masz wiele zmiennych czynników, możesz użyć funkcji select_if. zainstaluj pakiety dplyr. Istnieje wiele funkcji, które oddzielają dane przez spełnienie warunku. możesz ustawić warunki.

Użyj w ten sposób.

categorical<-select_if(df,is.factor)
str(categorical)
 1
Author: 서영재,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 00:19:05

To nie odpowiada bezpośrednio na pytanie, ale może być bardzo przydatne, zwłaszcza jeśli chcesz coś takiego jak wszystkie kolumny liczbowe 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))
 0
Author: RJMCMC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 16:32:46
Numerical_variables <- which(sapply(df, is.numeric))
# then extract column names 
Names <- names(Numerical_variables)
 0
Author: Mohamed ALI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-31 01:10:28