Вибір лише числових стовпців з кадру даних


189

Припустимо, у вас є такий data.frame:

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

Як би ви вибрали лише ті стовпці в x, які є числовими?

Відповіді:


289

EDIT: оновлено, щоб уникнути використання нераціональних порад 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)

10
x[nums]або x[sapply(x,is.numeric)]працює також. І вони завжди повертаються data.frame. Порівняйте x[1]vs x[,1]- перший - data.frameце вектор. Якщо ви хочете запобігти перетворенню, тоді слід скористатися x[, 1, drop=FALSE].
Марек

Будь-який спосіб вибору лише безперервних даних? Цей метод повертає як безперервне, так і ціле число.
Занедбане

Коли немає числового стовпця, виникає наступна помилка undefined columns selected. Як уникнути цього?
Йохан Обадія

@SoilSciGuy безперервні дані повинні бути як. числові. Можливо, у вас є дані про коефіцієнти, які є в числовій формі? Вам слід відкрити нове запитання.
Брендон Бертелсен

1
@YohanObadia Ви можете використовувати a tryCatch()для вирішення цього питання. Розгляньте питання щодо відкриття нового питання.
Брендон Бертелсен

79

Функція пакету dplyr select_if(- це елегантне рішення:

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

44

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 разів швидше).


Це рішення не виходить із ладу, коли немає числових стовпців. Чи є якісь недоліки в його використанні?
блі

Фільтр застосовується лише до рядків фрейму даних, а не до стовпців. Таким чином, це рішення не дасть правильного результату.
Майкл

4
@Michael не плутайте Filter з базового пакету та фільтруйте з пакету dplyr!
Кевін Зарка

1
@bli Я не бачу недоліків використання фільтра. Його вхід - це об'єкт data.frame, і він повертає data.frame
Кевін Зарка

Просто подзвоніть тут для довідки: те, Filter()що тут не працює, замінює, наприклад Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris), не буде працювати.
Збільшити Mobeus


5

Це альтернативний код для інших відповідей:

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

з data.table

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

3
Це скоріше коментар до обраної відповіді, а не аунік відповіді.
Брендон Бертельсен

2
Стовпці можуть мати більше одного класу.
Багатий скрипт


2

Бібліотека PCAmixdata має функціональний сплітмікс, який розділяє кількісні (числові дані) та якісні (категоричні дані) заданого фрейму даних "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)

2

Інший спосіб може бути таким:

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

1
Привіт Аюші, це, мабуть, було оскаржено, оскільки це повторення першої відповіді, але цей метод має деякі проблеми, які були визначені. Погляньте на коментарі в першій відповіді, ви побачите, що я маю на увазі.
Брендон Бертельсен

1

Якщо у вас багато змінних факторів, ви можете використовувати select_ifфункцію. встановити пакети dplyr. Існує багато функцій, що розділяють дані, задовольняючи умову. ви можете встановити умови.

Використовуйте так.

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

2
Виглядає як дублікат цієї попередньої відповіді stackoverflow.com/a/40808873/170352
Брендон Бертелсен

0

Це не відповідає безпосередньо на питання, але може бути дуже корисним, особливо якщо ви хочете щось подібне до всіх числових стовпців, за винятком стовпця id та залежної змінної.

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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.