Hanya baca kolom yang dipilih

134

Adakah yang bisa tolong beri tahu saya cara membaca hanya 6 bulan pertama (7 kolom) untuk setiap tahun dari data di bawah ini, misalnya dengan menggunakan 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
StarCub
sumber
5
Ini duplikat Cara hanya membaca kolom pilih dari file ke R? , Dirk menyebut tentang NULLkelas kolom dalam jawabannya .
Marek
stats.stackexchange.com/questions/16796/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件
2
@CiroSantilli 包子 露 宪 六四 事件 法轮功 yakin tapi ... saya bertanya dulu?
StarCub
Saya tidak menyiratkan hubungan yang lebih baik / lebih buruk. Lebih jauh lagi tidak ada duplikat lintas situs, jaringan pertukaran stack yang tidak konsisten memungkinkan mereka, kecuali jika Anda melakukan posting sendiri :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

157

Katakanlah data dalam file data.txt, Anda dapat menggunakan colClassesargumen read.table()untuk melewati kolom. Di sini, data dalam 7 kolom pertama adalah "integer"dan kami mengatur 6 kolom yang tersisa untuk "NULL"menunjukkan bahwa mereka harus dilewati

> 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

Ubah "integer"ke salah satu jenis yang diterima sebagai terperinci ?read.tabletergantung pada jenis data yang sebenarnya.

data.txt terlihat seperti ini:

$ 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

dan dibuat dengan menggunakan

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

di mana datadalah

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))

Jika jumlah kolom tidak diketahui sebelumnya, fungsi utilitas count.fieldsakan membaca file dan menghitung jumlah kolom di setiap baris.

## 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"))
Gavin Simpson
sumber
1
@Benjamin Baca beberapa baris pertama dari file menggunakan argumen nrows. Kemudian tentukan berapa banyak kolom yang ada gunakan ncol(), atau bagaimana pun Anda ingin menghitung jumlah kolom untuk dibaca / abaikan. Kemudian baca file lengkap menggunakan info ini.
Gavin Simpson
1
?? Jika Anda tidak tahu jumlah kolom, bagaimana Anda menentukannya tanpa membaca sedikit untuk menyimpulkan berapa banyak kolom?
Gavin Simpson
1
@ BlueMagister Terima kasih atas hasil edit dan penyebutannya count.fields()yang mengotomatiskan proses yang saya sarankan di komentar.
Gavin Simpson
1
@ LéoLéopoldHertz 준영 Tidak, dan saya tidak yakin bagaimana hal seperti itu akan bekerja untuk kelas baris seperti dalam bingkai data, sementara setiap kolom mungkin dari tipe yang berbeda, setiap baris, menurut definisi dan sebagai hasilnya, tidak dibatasi. Anda akan perlu menyaring baris kosong dll setelah impor.
Gavin Simpson
1
@ rmf Anda dapat melewati count.fields()koneksi teks, jadi, baca beberapa subset dari baris yang digunakan txt <- readLines(....), kemudian buat koneksi ke baris read in con <- textConnection(txt), lalu lakukan count.fields(txt). Pastikan untuk menggunakan skipdi count.fields()melewatkan baris header jika ada satu; Anda tidak dapat melewati baris dalam file menggunakan readLines().
Gavin Simpson
82

Untuk membaca kumpulan kolom tertentu dari dataset Anda, ada beberapa opsi lain:

1) Dengan freaddari data.table-paket:

Anda dapat menentukan kolom yang diinginkan dengan selectparameter dari freaddari data.tablepaket. Anda dapat menentukan kolom dengan vektor nama kolom atau nomor kolom.

Untuk dataset contoh:

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

Atau, Anda dapat menggunakan dropparameter untuk menunjukkan kolom mana yang tidak boleh dibaca:

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

Semua menghasilkan:

> 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

UPDATE: Ketika Anda tidak ingin freadmengembalikan data.table , gunakan data.table = FALSEparameter -m, misalnya:fread("data.txt", select = c(1:7), data.table = FALSE)

2) Dengan read.csv.sqldari sqldf-paket:

Alternatif lain adalah read.csv.sqlfungsi dari sqldfpaket:

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

3) Dengan -fungsi read_*dari readr-paket:

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______')

Dari dokumentasi penjelasan untuk karakter yang digunakan dengan col_types:

setiap karakter mewakili satu kolom: c = karakter, i = bilangan bulat, n = angka, d = ganda, l = logis, D = tanggal, T = waktu tanggal, t = waktu,? = tebak, atau _ / - untuk melewati kolom

Jaap
sumber
freadNamun, tidak mendukung file terkompresi. File besar biasanya terkompresi.
CoderGuy123
Ada permintaan fitur untuk mengaktifkan ini di fread. Yang perlu diperhatikan adalah freadkemungkinan besar akan membaca file yang tidak dikompresi lebih cepat daripada read.tablemembaca file yang dikompresi. Lihat di sini untuk contoh .
Jaap
Beberapa file yang tidak terkompresi terlalu besar. Misalnya saya bekerja dengan 1000 file Genom. Mereka bisa 60 GB tidak terkompresi.
CoderGuy123
1
Seperti yang mungkin Anda ketahui, R membaca data dalam memori. Apakah Anda membaca file zip atau file zip tidak membuat perbedaan pada ukuran data yang dihasilkan dalam memori. Jika Anda memiliki file 60GB, read.tabletidak akan menyelamatkan Anda. Dalam hal ini, Anda mungkin ingin melihat ff-paket.
Jaap
2
@Deleet Anda bisa menggunakan freaduntuk membaca file yang dikompresi besar seperti ini: fread("gunzip -c data.txt.gz", drop = c(8:13)).
arekolek
8

Anda juga bisa menggunakan JDBC untuk mencapai ini. Mari kita membuat file csv sampel.

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

Unduh dan simpan driver CSV JDBC dari tautan ini: http://sourceforge.net/projects/csvjdbc/files/latest/download

> 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
Rahul Premraj
sumber
0

Anda melakukannya seperti ini:

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)
tedtoal
sumber