Chuyển đổi cột data.frame thành một vectơ?


161

Tôi có một khung dữ liệu như:

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)

Tôi đã thử cách sau đây để chuyển đổi một trong các cột thành một vectơ, nhưng nó không hoạt động:

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

Đây là giải pháp duy nhất tôi có thể đưa ra, nhưng tôi cho rằng phải có cách tốt hơn để làm điều này:

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

Lưu ý: Từ vựng của tôi ở trên có thể bị tắt, vì vậy hãy sửa cho tôi nếu có. Tôi vẫn đang tìm hiểu thế giới của R. Ngoài ra, mọi lời giải thích về những gì đang diễn ra ở đây đều được đánh giá cao (nghĩa là liên quan đến Python hoặc một số ngôn ngữ khác sẽ có ích!)


5
Như bạn đang thấy trong các câu trả lời, việc đọc kỹ ?'[.data.frame'sẽ đưa bạn đi rất xa.
joran

Câu trả lời:


206

Tôi sẽ cố gắng giải thích điều này mà không mắc lỗi nào, nhưng tôi cá là điều này sẽ thu hút một hoặc hai ý kiến ​​làm rõ.

Một khung dữ liệu là một danh sách. Khi bạn đặt một khung dữ liệu bằng tên của một cột và [, thứ bạn nhận được là một danh sách con (hoặc khung dữ liệu phụ). Nếu bạn muốn cột nguyên tử thực tế, bạn có thể sử dụng [[, hoặc hơi khó hiểu (với tôi) bạn có thể làm điều aframe[,2]đó trả về một vectơ, không phải là một danh sách con.

Vì vậy, hãy thử chạy chuỗi này và có thể mọi thứ sẽ rõ ràng hơn:

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

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

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

6
+1 Điều này rất hữu ích. Tôi đã quen với việc sử dụng aframe[,"a2"]vì khả năng sử dụng điều này với cả khung dữ liệu và ma trận & dường như nhận được cùng một kết quả - một vectơ.
Lặp lại

8
[..., drop = F]sẽ luôn trả về khung dữ liệu
hadley

1
Điều này đặc biệt tốt để biết vì df$xcú pháp trả về một vectơ. Tôi đã sử dụng cú pháp này trong một thời gian dài, nhưng khi tôi phải bắt đầu sử dụng df['name']hoặc df[n]truy xuất các cột, tôi gặp vấn đề khi tôi cố gửi chúng đến các hàm mà vectơ mong đợi. Sử dụng df[[n]]hoặc df[['x']]xóa mọi thứ ngay lên.
rensa

8
Tại sao as.vectordường như âm thầm không có tác dụng? Không nên trả lại một vectơ hoặc thất bại rõ rệt?
bli

aframe[['a2']]rất hữu ích với sfcác đối tượng vì aframe[,"a2"]sẽ trả về hai cột vì cột hình học được bao gồm.
Matt

40

Bây giờ có một cách dễ dàng để làm điều này bằng cách sử dụng dplyr.

dplyr::pull(aframe, a2)

32

Bạn có thể sử dụng $trích xuất:

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

hoặc khung vuông đôi:

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

21

Bạn không cần as.vector(), nhưng bạn cần lập chỉ mục chính xác:avector <- aframe[ , "a2"]

Một điều khác cần lưu ý là drop=FALSEtùy chọn [:

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: Lời nhắc drop=FALSElà hữu ích - điều này giúp tôi trong trường hợp tôi có thể chọn N cột từ data.frame, trong những trường hợp có N = 1.
Lặp lại

Tôi sử dụng điều này khi tôi không thể thấy trước số lượng cột được chọn và trong trường hợp một cột xuất hiện, kết quả vẫn được truyền dưới dạng data.frame với n cột. Một vectơ có thể ném cờ lê khỉ vào các chức năng xuống dòng.
Roman Luštrik

11

Một ưu điểm khác của việc sử dụng toán tử '[[' là nó hoạt động cả với data.frame và data.table. Vì vậy, nếu hàm phải được thực hiện chạy cho cả data.frame và data.table và bạn muốn trích xuất một cột từ nó dưới dạng vector thì

data[["column_name"]] 

là tốt nhất.


8

Bạn có thể thử một cái gì đó như thế này-

as.vector(unlist(aframe$a2))

Điều này là tốt nếu bạn muốn so sánh hai cột bằng cách sử dụng identical.
p-robot

5

Nếu bạn chỉ sử dụng toán tử giải nén, nó sẽ hoạt động. Theo mặc định, [] đặt tùy chọn drop=TRUE, đó là những gì bạn muốn ở đây. Xem ?'['để biết thêm chi tiết.

>  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

Tôi sử dụng danh sách để lọc các tệp dữ liệu bằng cách chúng có giá trị% trong% danh sách hay không.

Tôi đã tạo các danh sách theo cách thủ công bằng cách xuất khung dữ liệu 1 cột sang Excel nơi tôi sẽ thêm "", xung quanh từng thành phần, trước khi dán vào danh sách R: list <- c ("el1", "el2", ...) thường theo sau là FilteredData <- tập hợp con (Dữ liệu, Cột% trong danh sách%).

Sau khi tìm kiếm stackoverflow và không tìm thấy một cách trực quan để chuyển đổi một khung dữ liệu 1 cột thành một danh sách, bây giờ tôi đang đăng đóng góp stackoverflow đầu tiên của mình:

# 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

Chúng ta cũng có thể chuyển đổi các cột data.frame thành một vectơ đơn giản. as.vectorlà không đủ vì nó giữ lại cấu trúc và lớp data.frame, vì vậy chúng ta cũng phải rút ra phần tử đầu tiên (và duy nhất):

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

Tất cả các giải pháp được đề xuất cho đến nay yêu cầu tiêu đề cột mã hóa cứng. Điều này làm cho chúng không chung chung (hãy tưởng tượng áp dụng điều này cho các đối số chức năng).

Ngoài ra, tất nhiên, bạn có thể đọc tên cột từ cột trước và sau đó chèn chúng vào mã trong các giải pháp khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.