Преобразовать столбец data.frame в вектор?


164

У меня есть датафрейм, такой как:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

Я попробовал следующее, чтобы преобразовать один из столбцов в вектор, но это не работает:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

Это единственное решение, которое я мог бы придумать, но я предполагаю, что должен быть лучший способ сделать это:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

Примечание: мой словарь выше может быть отключен, поэтому, пожалуйста, исправьте меня, если так. Я все еще изучаю мир R. Кроме того, приветствуется любое объяснение того, что здесь происходит (то есть отношение к Python или другому языку поможет!)


5
Как вы видите в ответах, внимательное прочтение ?'[.data.frame'приведет вас очень далеко.
Джоран

Ответы:


208

Я попытаюсь объяснить это, не делая ошибок, но я держу пари, что это привлечет одно или два уточнения в комментариях.

Фрейм данных - это список. Когда вы поднастраиваете фрейм данных, используя имя столбца и [, то, что вы получаете, это подсписок (или фрейм данных). Если вам нужен фактический атомарный столбец, вы можете использовать [[, или несколько запутанно (для меня), вы можете сделать, aframe[,2]который возвращает вектор, а не подсписок.

Так что попробуйте запустить эту последовательность, и, возможно, все будет яснее:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

6
+1 Это полезно. Я привык к использованию aframe[,"a2"]из-за возможности использовать это как с фреймами данных, так и с матрицами и, похоже, получаю одинаковые результаты - вектор.
Итератор

8
[..., drop = F]всегда будет возвращать фрейм данных
хэдли

1
Это особенно полезно знать, потому что df$xсинтаксис возвращает вектор. Я использовал этот синтаксис в течение длительного времени, но когда мне пришлось начать использовать df['name']или df[n]извлекать столбцы, у меня возникали проблемы, когда я пытался отправить их функциям, которые ожидали векторов. Использование df[[n]]или df[['x']]очистить вещи прямо вверх.
Ренса

8
Почему as.vectorкажется, что молча ничего не дает ? Не должно ли это либо вернуть вектор, либо явно потерпеть неудачу?
Бли

aframe[['a2']]очень полезно с sfобъектами, потому aframe[,"a2"]что вернет два столбца, потому что столбец геометрии включен.
Мэтт


32

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

class(aframe$a1)
[1] "numeric"

или двойная квадратная скобка:

class(aframe[["a1"]])
[1] "numeric"

21

Вам не нужно as.vector(), но вам нужна правильная индексация:avector <- aframe[ , "a2"]

Еще одна вещь, о которой нужно знать, это drop=FALSEвозможность [:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

4
+1: напоминание drop=FALSEполезно - это помогает мне в тех случаях, когда я могу выбрать N столбцов из data.frame, в тех случаях, когда N = 1.
Итератор

Я использую это, когда не могу предвидеть количество выбранных столбцов, и в случае появления одного столбца результат все равно передается как data.frame с n столбцами. Вектор может бросить гаечный ключ в функции вниз по линии.
Роман Луштрик

11

Другое преимущество использования оператора [[[] заключается в том, что он работает как с data.frame, так и с data.table. Таким образом, если функция должна быть запущена как для data.frame, так и для data.table, и вы хотите извлечь из нее столбец как вектор, тогда

data[["column_name"]] 

лучший.


8

Вы можете попробовать что-то вроде этого

as.vector(unlist(aframe$a2))

Это хорошо, если вы хотите сравнить два столбца, используя identical.
р-робот

5

Если вы просто используете оператор извлечения, он будет работать. По умолчанию [] устанавливает опцию drop=TRUE, которая вам здесь нужна. Смотрите ?'['для более подробной информации.

>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"


3
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

2

Я использую списки для фильтрации информационных фреймов по тому, имеют ли они значение% в% списка.

Я вручную создавал списки, экспортируя 1-столбцовый фрейм данных в Excel, где я добавил бы «» вокруг каждого элемента, прежде чем вставлять в R: list <- c («el1», «el2», ...), который обычно был затем следует FilteredData <- subset (Данные, Столбец% в списке%).

После поиска в stackoverflow и не найдя интуитивно понятного способа преобразования 1-столбцового кадра данных в список, я публикую свой первый в истории вклад в stackoverflow:

# assuming you have a 1 column dataframe called "df"
list <- c()
for(i in 1:nrow(df)){
  list <- append(list, df[i,1])
}
View(list)
# This list is not a dataframe, it is a list of values
# You can filter a dataframe using "subset([Data], [Column] %in% list")

1

Мы также можем преобразовать столбцы data.frame в общий вектор. as.vectorэтого недостаточно, поскольку он сохраняет класс и структуру data.frame, поэтому мы также должны извлечь первый (и единственный) элемент:

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

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

В качестве альтернативы вы можете, конечно, сначала прочитать имена столбцов из столбца, а затем вставить их в код других решений.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.