Предположим, у вас есть такой data.frame:
x <- data.frame(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])
Как бы вы выбрали только те столбцы в x, которые являются числовыми?
Предположим, у вас есть такой data.frame:
x <- data.frame(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])
Как бы вы выбрали только те столбцы в x, которые являются числовыми?
Ответы:
РЕДАКТИРОВАТЬ: обновлено, чтобы избежать использования опрометчивого sapply
.
Поскольку фрейм данных представляет собой список, мы можем использовать функции применения списка:
nums <- unlist(lapply(x, is.numeric))
Тогда стандартное подмножество
x[ , nums]
## don't use sapply, even though it's less code
## nums <- sapply(x, is.numeric)
Для более идиоматичного современного R я бы теперь рекомендовал
x[ , purrr::map_lgl(x, is.numeric)]
Менее запутанный, менее отражающий особенности R, более простой и надежный для использования в таблицах с базой данных:
dplyr::select_if(x, is.numeric)
undefined columns selected
. Как этого избежать?
tryCatch()
чтобы справиться с этим. Пожалуйста, подумайте об открытии нового вопроса.
Filter()
из базового пакета - идеальная функция для этого варианта использования: вам просто нужно написать код:
Filter(is.numeric, x)
Это также намного быстрее, чем select_if()
:
library(microbenchmark)
microbenchmark(
dplyr::select_if(mtcars, is.numeric),
Filter(is.numeric, mtcars)
)
возвращает (на моем компьютере) среднее значение 60 микросекунд для Filter
и 21 000 микросекунд для select_if
(в 350 раз быстрее).
Filter()
здесь не работает, - это замена, например Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris)
, не будет работать.
если вас интересуют только имена столбцов, используйте это:
names(dplyr::select_if(train,is.numeric))
Это альтернативный код другим ответам:
x[, sapply(x, class) == "numeric"]
с data.table
x[, lapply(x, is.numeric) == TRUE, with = FALSE]
Библиотека PCAmixdata имеет функцию splitmix, которая разделяет количественные (числовые данные) и качественные (категориальные данные) заданного фрейма данных YourDataframe, как показано ниже:
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)
Другой способ мог быть следующим: -
#extracting numeric columns from iris datset
(iris[sapply(iris, is.numeric)])
Если у вас много факторных переменных, вы можете использовать select_if
функцию. установить пакеты dplyr. Есть много функций, которые разделяют данные, удовлетворяя условию. вы можете установить условия.
Используйте вот так.
categorical<-select_if(df,is.factor)
str(categorical)
Это не дает прямого ответа на вопрос, но может быть очень полезным, особенно если вам нужно что-то вроде всех числовых столбцов, кроме столбца идентификатора и зависимой переменной.
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))
Numerical_variables <- which(sapply(df, is.numeric))
# then extract column names
Names <- names(Numerical_variables)
iris %>% dplyr::select(where(is.numeric)) #as per most recent updates
Другой вариант purrr
- отрицать discard
функцию:
iris %>% purrr::discard(~!is.numeric(.))
Если вам нужны имена числовых столбцов, вы можете добавить names
или colnames
:
iris %>% purrr::discard(~!is.numeric(.)) %>% names
x[nums]
илиx[sapply(x,is.numeric)]
тоже работает. И они всегда возвращаютсяdata.frame
. Сравнитьx[1]
vsx[,1]
- первоеdata.frame
, второе - вектор. Если кто-то хочет предотвратить преобразование, необходимо использоватьx[, 1, drop=FALSE]
.