Saya memiliki sejumlah kolom yang ingin saya hapus dari bingkai data. Saya tahu bahwa kami dapat menghapusnya secara individual menggunakan sesuatu seperti:
df$x <- NULL
Tetapi saya berharap untuk melakukan ini dengan lebih sedikit perintah.
Juga, saya tahu bahwa saya dapat menjatuhkan kolom menggunakan pengindeksan bilangan bulat seperti ini:
df <- df[ -c(1, 3:6, 12) ]
Tetapi saya khawatir bahwa posisi relatif dari variabel saya dapat berubah.
Mengingat betapa kuatnya R, saya pikir mungkin ada cara yang lebih baik daripada menjatuhkan setiap kolom satu per satu.
df#drop(var_name)
, dan sebagai gantinya, kita perlu melakukan pekerjaan rumit ini?Jawaban:
Anda dapat menggunakan daftar nama sederhana:
Atau, sebagai alternatif, Anda dapat membuat daftar untuk disimpan dan merujuknya dengan nama:
EDIT: Bagi yang masih belum terbiasa dengan
drop
argumen fungsi pengindeksan, jika Anda ingin menyimpan satu kolom sebagai bingkai data, Anda harus:drop=TRUE
(atau tidak menyebutkannya) akan menjatuhkan dimensi yang tidak perlu, dan karenanya mengembalikan vektor dengan nilai kolomy
.sumber
DF[,keeps]
bukanDF[keeps]
?Ada juga
subset
perintahnya, berguna jika Anda tahu kolom mana yang Anda inginkan:DIPERBARUI setelah komentar oleh @hadley: Untuk menjatuhkan kolom a, c Anda dapat melakukan:
sumber
subset
fungsi R memiliki opsi seperti "allbut = FALSE", yang "membalikkan" pilihan ketika diatur ke TRUE, yaitu mempertahankan semua kolom kecuali yang ada dalamselect
daftar.df[c("a", "c")]
subset
perintah di mana Anda tidak perlu memberi tanda kutip di sekitar nama kolom - Saya kira saya tidak keberatan mengetik beberapa karakter tambahan hanya untuk menghindari mengutip nama :)subset
di dalam fungsi lain.mungkin paling mudah, atau untuk banyak variabel:
Atau jika Anda berurusan dengan
data.table
s (per Bagaimana Anda menghapus kolom dengan nama di data.table? ):atau untuk beberapa variabel
sumber
within(df, rm(x))
adalah jauh solusi yang bersih. Mengingat bahwa ini adalah suatu kemungkinan, setiap jawaban lain tampaknya tidak perlu rumit oleh urutan besarnya.within(df, rm(x))
akan tidak bekerja jika ada duplikat kolom bernamax
didf
.df <- data.frame(x = 1, y = 2); names(df) <- c("x", "x"); within(df, rm(x))
pengembaliandata.frame(x = 2, x = 2)
.within()
yang kuat tetapi juga menggunakan NSE. Catatan pada halaman bantuan menyatakan dengan jelas bahwa untuk pemrograman, perawatan yang memadai harus digunakan.Anda bisa menggunakan
%in%
seperti ini:sumber
DF[ , !(names(DF) %in% drops)]
identical(post_time_1, post_time_2) [1] TRUE
= Ddaftar (NULL) juga berfungsi:
sumber
Jika Anda ingin menghapus kolom dengan referensi dan menghindari penyalinan internal yang terkait dengan
data.frames
maka Anda dapat menggunakandata.table
paket dan fungsinya:=
Anda dapat melewatkan nama-nama vektor karakter ke sisi kiri menu
:=
operator, danNULL
sebagai RHS.Jika Anda ingin menentukan nama sebagai vektor karakter di luar panggilan
[
, bungkus nama objek di dalam()
atau{}
untuk memaksa LHS dievaluasi dalam ruang lingkup panggilan bukan sebagai nama dalam ruang lingkupDT
.Anda juga dapat menggunakan
set
, yang menghindari overhead[.data.table
, dan juga berfungsi untukdata.frames
!sumber
Ada strategi yang berpotensi lebih kuat berdasarkan fakta bahwa grep () akan mengembalikan vektor numerik. Jika Anda memiliki daftar panjang variabel seperti yang saya lakukan di salah satu dataset saya, beberapa variabel yang berakhiran ".A" dan yang lainnya berakhiran ".B" dan Anda hanya ingin yang berakhiran ".A" (bersama dengan semua variabel yang tidak cocok dengan pola mana pun, lakukan ini:
Untuk kasus yang dihadapi, menggunakan contoh Joris Meys, mungkin tidak sekompak, tetapi akan menjadi:
sumber
drops
di tempat pertama sebagaipaste0("^", drop_cols, "$")
, ini menjadi jauh lebih baik (baca: lebih kompak) dengansapply
:DF[ , -sapply(drops, grep, names(DF))]
dplyr
Jawaban lain Jika variabel Anda memiliki beberapa struktur penamaan yang sama, Anda dapat mencobastarts_with()
. Sebagai contohJika Anda ingin menjatuhkan urutan variabel dalam bingkai data, Anda bisa menggunakan
:
. Sebagai contoh jika Anda ingin menjatuhkanvar2
,var3
dan semua variabel di antara, Anda baru saja ditinggalkan denganvar1
:sumber
select()
, seperticontains()
ataumatches()
, yang juga menerima regex.Kemungkinan lain:
atau
sumber
setdiff
yang optimal terutama dalam kasus jumlah kolom yang sangat besar.df <- df[ , -which(grepl('a|c', names(df)))]
Keluaran:
Keluaran:
sumber
Solusi Dplyr
Saya ragu ini akan mendapat banyak perhatian di sini, tetapi jika Anda memiliki daftar kolom yang ingin Anda hapus, dan Anda ingin melakukannya dalam
dplyr
rantai yang saya gunakanone_of()
diselect
klausa:Berikut adalah contoh sederhana dan dapat direproduksi:
Dokumentasi dapat ditemukan dengan menjalankan
?one_of
atau di sini:http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
sumber
Karena ketertarikan, ini menandai salah satu inkonsistensi sintaksis ganda R yang aneh. Misalnya diberi kerangka data dua kolom:
Ini memberikan bingkai data
tetapi ini memberikan vektor
Ini semua dijelaskan
?[
tetapi itu bukan perilaku yang diharapkan. Yah setidaknya tidak bagiku ...sumber
Ini
dplyr
cara untuk melakukannya:Saya suka ini karena intuitif untuk membaca & memahami tanpa penjelasan dan kuat untuk kolom yang mengubah posisi dalam bingkai data. Ini juga mengikuti idiom vektor yang digunakan
-
untuk menghapus elemen.sumber
%<>%
operator untuk mengganti objek input itu dapat disederhanakan menjadidf %<>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)
dplyr
, mungkin akan lebih mudah untuk mengelompokkannya dan hanya menempatkan satu minus:df.cut <- df %>% select(-c(col.to.drop.1, col.to.drop.2, ..., col.to.drop.n))
Saya terus berpikir harus ada idiom yang lebih baik, tetapi untuk pengurangan kolom dengan nama, saya cenderung melakukan hal berikut:
sumber
df[,-match(c("e","f"),names(df))]
-
?Ada fungsi yang disebut
dropNamed()
dalamBBmisc
paket Bernd Bischl yang melakukan hal ini.Keuntungannya adalah ia menghindari pengulangan argumen bingkai data dan karenanya cocok untuk disalurkan
magrittr
(sepertidplyr
pendekatan):sumber
Solusi lain jika Anda tidak ingin menggunakan @ hadley di atas: Jika "COLUMN_NAME" adalah nama kolom yang ingin Anda jatuhkan:
sumber
COLUMN_NAME
tidak didf
(periksa sendiri:)df<-data.frame(a=1,b=2)
. (3)df[,names(df) != "COLUMN_NAME"]
lebih sederhana dan tidak menderita (2)Di luar yang
select(-one_of(drop_col_names))
diperlihatkan dalam jawaban sebelumnya, ada beberapadplyr
opsi lain untuk menjatuhkan kolom menggunakanselect()
yang tidak melibatkan mendefinisikan semua nama kolom tertentu (menggunakan data sampel starwars dplyr untuk beberapa variasi dalam nama kolom):Jika Anda perlu menjatuhkan kolom yang mungkin atau mungkin tidak ada dalam bingkai data, inilah sedikit twist menggunakan
select_if()
yang tidak seperti menggunakanone_of()
tidak akan memberikanUnknown columns:
peringatan jika nama kolom tidak ada. Dalam contoh ini 'bad_column' bukan kolom di bingkai data:sumber
Berikan bingkai data dan serangkaian nama yang dipisahkan koma untuk dihapus:
Penggunaan :
sumber
Temukan indeks kolom yang ingin Anda jatuhkan
which
. Berikan indeks ini tanda negatif (*-1
). Kemudian subset pada nilai-nilai itu, yang akan menghapusnya dari dataframe. Ini sebuah contoh.sumber
Jika Anda memiliki
data.frame
memori yang besar dan rendah[
. . . . ataurm
danwithin
untuk menghapus kolom adata.frame
, sepertisubset
saat ini (R 3.6.2) menggunakan lebih banyak memori - di samping petunjuk manual untuk menggunakan secarasubset
interaktif .sumber