Извлечение определенных столбцов из фрейма данных

У меня есть фрейм данных R с 6 столбцами, и я хочу создать новый фрейм данных, в котором есть только три столбца.

Предполагая, что мой фрейм данных df, и я хочу извлечь столбцы A, B и E, это единственная команда, которую я могу понять:

 data.frame(df$A,df$B,df$E)

Есть ли более компактный способ сделать это?


person Aren Cambre    schedule 10.04.2012    source источник


Ответы (10)


Используя пакет dplyr, если ваш data.frame называется df1:

library(dplyr)

df1 %>%
  select(A, B, E)

Это также можно записать без канала %>% как:

select(df1, A, B, E)
person Sam Firke    schedule 19.04.2015
comment
Учитывая значительную эволюцию Tidyverse с момента публикации моего вопроса, я переключил ответ на вас. - person Aren Cambre; 16.08.2018
comment
Учитывая бешеную скорость изменения тидиверсии, я бы предостерегал от использования этого паттерна. Это в дополнение к моему сильному предпочтению не рассматривать имена столбцов как имена объектов при написании кода для функций, пакетов или приложений. - person Joshua Ulrich; 22.05.2019
comment
С момента отправки этого ответа прошло более четырех лет, и картина не изменилась. Конвейерные выражения могут быть довольно интуитивно понятными, поэтому они и привлекательны. - person Aren Cambre; 25.06.2019
comment
как мне выполнить дополнительную команду для этого подмножества? Например. Я хочу вычислить rowMean: df1% ›% rowMeans (select (A, B, E)) не работает. - person Ben; 11.05.2020
comment
Вы бы соединили конвейер, например: df1 %>% select(A, B, E) %>% rowMeans(.). См. Документацию по каналу %>%, набрав ?magrittr::`%>%` - person Sam Firke; 11.05.2020

Вы можете подмножество, используя вектор имен столбцов. Я настоятельно предпочитаю этот подход тем, которые обрабатывают имена столбцов, как если бы они были именами объектов (например, subset()), особенно при программировании в функциях, пакетах или приложениях.

# data for reproducible example
# (and to avoid confusion from trying to subset `stats::df`)
df <- setNames(data.frame(as.list(1:5)), LETTERS[1:5])
# subset
df[c("A","B","E")]

Обратите внимание, что запятой нет (т.е. это не df[,c("A","B","C")]). Это потому, что df[,"A"] возвращает вектор, а не фрейм данных. Но df["A"] всегда будет возвращать фрейм данных.

str(df["A"])
## 'data.frame':    1 obs. of  1 variable:
## $ A: int 1
str(df[,"A"])  # vector
##  int 1

Спасибо Дэвиду Дорчису за указание из того, что df[,"A"] возвращает вектор вместо data.frame, и Антуану Фабри для предложения лучшей альтернативы (см. выше ) к моему исходному решению (ниже).

# subset (original solution--not recommended)
df[,c("A","B","E")]  # returns a data.frame
df[,"A"]             # returns a vector
person Joshua Ulrich    schedule 10.04.2012
comment
Это дает ошибку object of type 'closure' is not subsettable. - person Aren Cambre; 10.04.2012
comment
@ArenCambre: тогда ваш data.frame на самом деле не называется df. df также является функцией пакета статистики. - person Joshua Ulrich; 10.04.2012
comment
@ArenCambre: 2.bp.blogspot.com/-XU9PduVhq-I/Um-Y6e19jZI/AAAAAAAADfI/ - person tumultous_rooster; 20.01.2015
comment
но почему этот не работает df[,-c("A","B","E")]? - person Cina; 27.06.2015
comment
@Cina: Потому что -"A" - синтаксическая ошибка. И ?Extract говорит, что i, j, ... также могут быть отрицательными целыми числами, указывая на элементы / фрагменты, которые следует исключить из выбора. - person Joshua Ulrich; 27.06.2015
comment
Я получаю SyntaxError: invalid syntax, когда использую это. - person Richard; 17.12.2015
comment
@ Ричард: Я не знаю, что тебе сказать; это, безусловно, правильный синтаксис. Я также добавил воспроизводимый пример. - person Joshua Ulrich; 17.12.2015
comment
Существует проблема с этим синтаксисом, потому что, если мы извлекаем только один столбец R, возвращает вектор вместо фрейма данных, и это может быть нежелательным: > df[,c("A")] [1] 1. Использование subset лишено этого недостатка. - person David Dorchies; 27.07.2016
comment
Я заметил, что использование вектора символов имен столбцов часто не работает, когда у меня загружен пакет data.table. В таких случаях лучше использовать один из других методов: subset() или dplyr select(). - person Paul de Barros; 02.11.2016
comment
@PauldeBarros: загружен ли data.table не имеет значения, если только объект, который вы пытаетесь подмножество, не является data.table, а не data.frame. Этот вопрос касается подмножества data.frame, а не data.table. - person Joshua Ulrich; 02.11.2016
comment
@JoshuaUlrich: Я уверен, что ты прав. Объекты, которые создают проблемы, относятся к классам data.frame и data.table (согласно str). Без загруженной таблицы data.table те же объекты являются просто data.frames. Я не понимал, что загрузка data.table перед запуском моего кода изменит класс этих объектов. Тот факт, что предоставленный вами метод (и который я использовал) внезапно перестал работать, меня удивил, и я подумал, что другим может быть полезно знать, что поведение их кода может измениться в этих обстоятельствах. - person Paul de Barros; 02.11.2016
comment
Может лучше df[c("A","B","E")] (без запятой)? мы выигрываем одного персонажа и решаем проблему, на которую указал @ david-dorchies - person Moody_Mudskipper; 22.05.2019
comment
@Moody_Mudskipper Лучше установить аргумент drop = FALSE: df[, "A", drop = FALSE]. - person Rui Barradas; 30.06.2020
comment
При подмножестве списка аргумент drop не нужен, я имел в виду именно это. df["A"] в порядке. - person Moody_Mudskipper; 30.06.2020

Это роль subset() функция:

> dat <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> subset(dat, select=c("A", "B"))
  A B
1 1 3
2 2 4
person Stéphane Laurent    schedule 10.04.2012
comment
Когда я пытаюсь это сделать с моими данными, я получаю сообщение об ошибке: Ошибка в x [j]: недопустимый индекс типа 'list' Но если c (A, B) не является списком, что это? - person Rafael_Espericueta; 28.11.2016
comment
@Rafael_Espericueta Трудно угадать, не просматривая код ... Но c("A", "B") - это вектор, а не список. - person Stéphane Laurent; 28.11.2016
comment
Он преобразует фрейм данных в список. - person Suat Atan PhD; 21.06.2017

Есть два очевидных варианта: df[,c("A","B","E")] Джошуа Ульриха или

df[,c(1,2,5)]

as in

> df <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> df
  A B C D E F
1 1 3 5 7 8 9
2 2 4 6 7 8 9
> df[,c(1,2,5)]
  A B E
1 1 3 8
2 2 4 8
> df[,c("A","B","E")]
  A B E
1 1 3 8
2 2 4 8
person Henry    schedule 10.04.2012

Только по какой-то причине

df[, (names(df) %in% c("A","B","E"))]

работал у меня. Все вышеперечисленные синтаксисы привели к «выбранным неопределенным столбцам».

person so860    schedule 12.10.2017

Где df1 - ваш исходный фрейм данных:

df2 <- subset(df1, select = c(1, 2, 5))
person Richard Ball    schedule 10.06.2016
comment
Здесь не используется dplyr. Он использует base::subset и идентичен ответу Стефана Лорана, за исключением того, что вы используете номера столбцов вместо имен столбцов. - person Gregor Thomas; 12.10.2017

Вы также можете использовать пакет sqldf, который выполняет выборку кадров данных R как:

df1 <- sqldf("select A, B, E from df")

Это дает в качестве вывода фрейм данных df1 со столбцами: A, B, E.

person Aman Burman    schedule 30.11.2016

Вы можете использовать with:

with(df, data.frame(A, B, E))
person Moody_Mudskipper    schedule 22.05.2019

[ и подмножество не подлежат замене:

[ возвращает вектор, если выбран только один столбец.

df = data.frame(a="a",b="b")    

identical(
  df[,c("a")], 
  subset(df,select="a")
) 

identical(
  df[,c("a","b")],  
  subset(df,select=c("a","b"))
)
person fxi    schedule 09.11.2016
comment
Нет, если вы установите drop=FALSE. Пример: df[,c("a"),drop=F] - person untill; 19.09.2017

df<- dplyr::select ( df,A,B,C)

Кроме того, вы можете присвоить новое имя вновь созданным данным.

data<- dplyr::select ( df,A,B,C)
person Mohamed Rahouma    schedule 15.10.2019