Перетворити стовпчик data.frame у вектор?


163

У мене є такий кадр даних, як:

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"

Примітка. Моя лексика вище може бути вимкнена, тому, будь ласка, виправте мене. Я все ще вивчаю світ Р. Крім того, будь-яке пояснення того, що тут відбувається, цінується (тобто стосується Python чи іншої мови допоможе!)


5
Як ви бачите у відповідях, уважне читання ?'[.data.frame'пройде дуже далеко.
joran

Відповіді:


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]завжди повертає кадр даних
hadley

1
Це особливо добре знати, оскільки df$xсинтаксис повертає вектор. Я довго використовував цей синтаксис, але коли мені довелося почати використовувати df['name']або df[n]витягувати стовпці, у мене виникли проблеми, коли я намагався надсилати їх до функцій, які очікували вектори. Використання df[[n]]або df[['x']]очищення речей прямо.
rensa

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 стовпців із фрейму даних, у тих випадках, коли N = 1.
Ітератор

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

11

Ще одна перевага використання оператора "[[" полягає в тому, що він працює як з data.frame, так і з data.table. Отже, якщо функцію потрібно запустити як для data.frame, так і для data.table, і ви хочете витягнути стовпчик з нього як вектор, то

data[["column_name"]] 

найкраще.


8

Ви можете спробувати щось подібне -

as.vector(unlist(aframe$a2))

Це добре, якщо ви хочете порівняти два стовпці, використовуючи identical.
p-робот

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 <- підмножина (Дані, стовпець% у списку%).

Після пошуку 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.