Chỉ đọc các cột được chọn


134

Bất cứ ai có thể vui lòng cho tôi biết làm thế nào để chỉ đọc 6 tháng đầu (7 cột) cho mỗi năm của dữ liệu dưới đây, ví dụ bằng cách sử dụng read.table()?

Year   Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec   
2009   -41  -27  -25  -31  -31  -39  -25  -15  -30  -27  -21  -25
2010   -41  -27  -25  -31  -31  -39  -25  -15  -30  -27  -21  -25 
2011   -21  -27   -2   -6  -10  -32  -13  -12  -27  -30  -38  -29

5
Đó là bản sao Cách chỉ đọc các cột từ tệp vào R? , Dirk đề cập đến NULLnhư là lớp cột trong câu trả lời của mình .
Marek


2
@CiroSantilli 露 宪 六四 事件 chắc chắn nhưng ... tôi đã hỏi trước?
StarCub

Tôi đã không ngụ ý một mối quan hệ tốt hơn / xấu hơn. Hơn nữa, không có trùng lặp trang web chéo, mạng trao đổi ngăn xếp không nhất quán cho phép chúng, trừ khi bạn tự đăng bài :-)
Ciro Santilli 冠状 病 六四 法轮功

Câu trả lời:


157

Giả sử dữ liệu có trong tệp data.txt, bạn có thể sử dụng colClassesđối số read.table()để bỏ qua các cột. Ở đây, dữ liệu trong 7 cột đầu tiên là "integer"và chúng tôi đặt 6 cột còn lại để "NULL"chỉ ra rằng chúng nên được bỏ qua

> read.table("data.txt", colClasses = c(rep("integer", 7), rep("NULL", 6)), 
+            header = TRUE)
  Year Jan Feb Mar Apr May Jun
1 2009 -41 -27 -25 -31 -31 -39
2 2010 -41 -27 -25 -31 -31 -39
3 2011 -21 -27  -2  -6 -10 -32

Thay đổi "integer"thành một trong các loại được chấp nhận như chi tiết ?read.tabletùy thuộc vào loại dữ liệu thực.

data.txt trông như thế này:

$ cat data.txt 
"Year" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
2009 -41 -27 -25 -31 -31 -39 -25 -15 -30 -27 -21 -25
2010 -41 -27 -25 -31 -31 -39 -25 -15 -30 -27 -21 -25
2011 -21 -27 -2 -6 -10 -32 -13 -12 -27 -30 -38 -29

và được tạo ra bằng cách sử dụng

write.table(dat, file = "data.txt", row.names = FALSE)

nơi dat

dat <- structure(list(Year = 2009:2011, Jan = c(-41L, -41L, -21L), Feb = c(-27L, 
-27L, -27L), Mar = c(-25L, -25L, -2L), Apr = c(-31L, -31L, -6L
), May = c(-31L, -31L, -10L), Jun = c(-39L, -39L, -32L), Jul = c(-25L, 
-25L, -13L), Aug = c(-15L, -15L, -12L), Sep = c(-30L, -30L, -27L
), Oct = c(-27L, -27L, -30L), Nov = c(-21L, -21L, -38L), Dec = c(-25L, 
-25L, -29L)), .Names = c("Year", "Jan", "Feb", "Mar", "Apr", 
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"), class = "data.frame",
row.names = c(NA, -3L))

Nếu số lượng cột không được biết trước, hàm tiện ích count.fieldssẽ đọc qua tệp và đếm số lượng trường trong mỗi dòng.

## returns a vector equal to the number of lines in the file
count.fields("data.txt", sep = "\t")
## returns the maximum to set colClasses
max(count.fields("data.txt", sep = "\t"))

1
@Benjamin Đọc vài dòng đầu tiên từ tệp bằng đối số nrows. Sau đó tìm ra có bao nhiêu cột đang sử dụng ncol(), hoặc tuy nhiên bạn muốn tìm ra số lượng cột cần đọc / bỏ qua. Sau đó đọc các tập tin đầy đủ bằng cách sử dụng thông tin này.
Gavin Simpson

1
?? Nếu bạn không biết số lượng cột, bạn sẽ xác định nó như thế nào mà không cần đọc một chút về cột để suy ra có bao nhiêu cột?
Gavin Simpson

1
@BlueMagister Cảm ơn bạn đã chỉnh sửa và đề cập đến việc count.fields()tự động hóa quy trình tôi đề xuất trong các nhận xét.
Gavin Simpson

1
@ LéoLéopoldHertz Không, và tôi không chắc một thứ như vậy sẽ hoạt động như thế nào đối với các lớp hàng như trong khung dữ liệu, trong khi mỗi cột có thể thuộc một loại khác nhau, mỗi hàng, theo định nghĩa và do đó, không bị ràng buộc. Bạn sẽ cần phải lọc ra các hàng trống, vv khi nhập.
Gavin Simpson

1
@rmf bạn có thể truyền count.fields()kết nối văn bản, vì vậy, hãy đọc một số tập hợp con của các hàng bằng cách sử dụng txt <- readLines(....), sau đó tạo kết nối để đọc trong dòng con <- textConnection(txt), sau đó làm count.fields(txt). Hãy chắc chắn để sử dụng skiptrong count.fields()để bỏ qua dòng tiêu đề nếu có một; bạn không thể bỏ qua các hàng trong tệp bằng cách sử dụng readLines().
Gavin Simpson

82

Để đọc một tập hợp các cột cụ thể từ bộ dữ liệu bạn, có một số tùy chọn khác:

1) Với freadtừ data.table-package:

Bạn có thể chỉ định các cột mong muốn với các selecttham số từ freadtừ data.tablegói. Bạn có thể chỉ định các cột với một vectơ tên cột hoặc số cột.

Đối với tập dữ liệu mẫu:

library(data.table)
dat <- fread("data.txt", select = c("Year","Jan","Feb","Mar","Apr","May","Jun"))
dat <- fread("data.txt", select = c(1:7))

Ngoài ra, bạn có thể sử dụng droptham số để chỉ ra những cột nào không nên đọc:

dat <- fread("data.txt", drop = c("Jul","Aug","Sep","Oct","Nov","Dec"))
dat <- fread("data.txt", drop = c(8:13))

Tất cả kết quả trong:

> data
  Year Jan Feb Mar Apr May Jun
1 2009 -41 -27 -25 -31 -31 -39
2 2010 -41 -27 -25 -31 -31 -39
3 2011 -21 -27  -2  -6 -10 -32

CẬP NHẬT: Khi bạn không muốn freadtrả về data.table , hãy sử dụng tham số data.table = FALSE, ví dụ:fread("data.txt", select = c(1:7), data.table = FALSE)

2) Với read.csv.sqltừ sqldf-package:

Một cách khác là read.csv.sqlchức năng từ sqldfgói:

library(sqldf)
dat <- read.csv.sql("data.txt",
                    sql = "select Year,Jan,Feb,Mar,Apr,May,Jun from file",
                    sep = "\t")

3) Với các read_*-fifts từ readr-package:

library(readr)
dat <- read_table("data.txt",
                  col_types = cols_only(Year = 'i', Jan = 'i', Feb = 'i', Mar = 'i',
                                        Apr = 'i', May = 'i', Jun = 'i'))
dat <- read_table("data.txt",
                  col_types = list(Jul = col_skip(), Aug = col_skip(), Sep = col_skip(),
                                   Oct = col_skip(), Nov = col_skip(), Dec = col_skip()))
dat <- read_table("data.txt", col_types = 'iiiiiii______')

Từ tài liệu giải thích cho các ký tự được sử dụng với col_types:

mỗi ký tự đại diện cho một cột: c = character, i = số nguyên, n = number, d = double, l = logic, D = date, T = date time, t = time ,? = đoán hoặc _ / - để bỏ qua cột


freadkhông hỗ trợ các tập tin nén, tuy nhiên. Các tệp lớn thường được nén.
CoderGuy123

Có một yêu cầu tính năng để kích hoạt tính năng này fread. Đáng chú ý là freadrất có thể sẽ đọc tệp không nén nhanh hơn đáng kể so với việc read.tableđọc tệp nén. Xem ở đây cho một ví dụ .
Jaap

Một số tệp không nén quá lớn. Ví dụ: tôi đang làm việc với 1000 tệp Genomes. Chúng có thể là 60 GB không nén.
CoderGuy123

1
Như bạn có thể biết, R đọc dữ liệu trong bộ nhớ. Cho dù bạn đọc tệp nén hay tệp giải nén không tạo ra sự khác biệt về kích thước của dữ liệu kết quả trong bộ nhớ. Nếu bạn có 60GB trong các tệp, read.tablesẽ không giúp bạn tiết kiệm. Trong trường hợp đó, bạn có thể muốn xem xét ff-package.
Jaap

2
@Deleet Bạn có thể sử dụng freadđể đọc các tệp nén lớn như thế này : fread("gunzip -c data.txt.gz", drop = c(8:13)).
arekolek

8

Bạn cũng có thể sử dụng JDBC để đạt được điều này. Hãy tạo một tệp csv mẫu.

write.table(x=mtcars, file="mtcars.csv", sep=",", row.names=F, col.names=T) # create example csv file

Tải xuống và lưu trình điều khiển JDBC CSV từ liên kết này: http://sourceforge.net/projects/csvjdbc/files/latest/doad

> library(RJDBC)

> path.to.jdbc.driver <- "jdbc//csvjdbc-1.0-18.jar"
> drv <- JDBC("org.relique.jdbc.csv.CsvDriver", path.to.jdbc.driver)
> conn <- dbConnect(drv, sprintf("jdbc:relique:csv:%s", getwd()))

> head(dbGetQuery(conn, "select * from mtcars"), 3)
   mpg cyl disp  hp drat    wt  qsec vs am gear carb
1   21   6  160 110  3.9  2.62 16.46  0  1    4    4
2   21   6  160 110  3.9 2.875 17.02  0  1    4    4
3 22.8   4  108  93 3.85  2.32 18.61  1  1    4    1

> head(dbGetQuery(conn, "select mpg, gear from mtcars"), 3)
   MPG GEAR
1   21    4
2   21    4
3 22.8    4

0

Bạn làm như thế này:

df = read.table("file.txt", nrows=1, header=TRUE, sep="\t", stringsAsFactors=FALSE)
colClasses = as.list(apply(df, 2, class))
needCols = c("Year", "Jan", "Feb", "Mar", "Apr", "May", "Jun")
colClasses[!names(colClasses) %in% needCols] = list(NULL)
df = read.table("file.txt", header=TRUE, colClasses=colClasses, sep="\t", stringsAsFactors=FALSE)
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.