R dplyr: Menurunkan beberapa kolom


96

Saya memiliki dataframe dan daftar kolom dalam dataframe yang ingin saya hapus. Mari gunakan irisdataset sebagai contoh. Saya ingin melepas Sepal.Lengthdan Sepal.Widthdan hanya menggunakan kolom yang tersisa. Bagaimana cara melakukannya menggunakan selectatau select_dari dplyrpaket?

Inilah yang saya coba sejauh ini:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

Kesalahan dalam -drop.cols: argumen tidak valid ke operator unary

iris %>% select_(.dots = -drop.cols)

Kesalahan dalam -drop.cols: argumen tidak valid ke operator unary

iris %>% select(!drop.cols)

Kesalahan dalam! Drop.cols: tipe argumen tidak valid

iris %>% select_(.dots = !drop.cols)

Kesalahan dalam! Drop.cols: tipe argumen tidak valid

Saya merasa seperti saya kehilangan sesuatu yang jelas karena ini sepertinya operasi yang cukup berguna yang seharusnya sudah ada. Di Github, seseorang memposting masalah serupa , dan Hadley mengatakan untuk menggunakan 'pengindeksan negatif'. Itulah yang (menurut saya) saya coba, tetapi tidak berhasil. Ada saran?

Jawaban:


127

Periksa bantuan di select_vars. Itu memberi Anda beberapa gagasan tambahan tentang cara bekerja dengan ini.

Dalam kasus Anda:

iris %>% select(-one_of(drop.cols))

Terima kasih. Untuk beberapa alasan, ini berfungsi iris, tetapi tidak pada kerangka data saya yang sebenarnya ( irisadalah contoh mainan). Dataframe saya berisi 4558 baris dan 147 kolom. Pesan kesalahan yang saya terima adalah Error in eval(x$expr, data, x$env) : variable names are limited to 10000 bytes. Adakah yang tahu mengapa ini mungkin terjadi?
Navaneethan Santhanam

1
Ah, sepertinya saya melakukan kesalahan. Saya tidak sengaja menggunakan select_varssebagai gantinya select. Sekarang bekerja dengan sempurna!
Navaneethan Santhanam

5
Di mana kita bisa mencari tahu tentang fungsi bawaan one_of? Kecuali saya melewatkan sesuatu, itu tidak muncul di dokumentasi paket ( help(package='dplyr')).
geotheory

4
@geotheory, sebenarnya one_of didokumentasikan. lihat help(one_of, package = "dplyr"). Setidaknya dalam versi paket 0.5.0. Tapi ada baiknya membaca blog yang Hadley posting ketika ada update ke salah satu paketnya. Dan beberapa fungsi didokumentasikan di dalam fungsi lainnya. Sayangnya itu membutuhkan membaca semua dokumentasi, yang kebanyakan saya lakukan ketika saya menginginkan sesuatu yang tidak segera terlihat atau mungkin dengan fungsinya.
phiver

10
Terima kasih. Bagaimana Anda mengetahui tentang fungsi-fungsi ini sejak awal, dalam hal dokumentasi?
geotheory

67

juga coba

## Notice the lack of quotes
iris %>% select (-c(Sepal.Length, Sepal.Width))

5
Bagus! Sangat berguna ketika kita harus melepaskan kolom dengan menyalin-tempel nama dari konsol.
Pablo Casas

37

Di luar select(-one_of(drop.cols))ada beberapa opsi lain untuk menjatuhkan kolom menggunakan select()yang tidak melibatkan mendefinisikan semua nama kolom tertentu (menggunakan data sampel dplyr starwars untuk beberapa variasi lagi dalam nama kolom):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

Apakah select_if(~!is.list(.))setara dengan select_if(is.list(.))?
Jasha

3
Dalam hal ini ~adalah singkatan purrr untuk mendefinisikan suatu fungsi anonamous, itu bukan simbol lain untuk tidak. Misalnya keduanya memiliki arti yang sama function(x) {!is.list(x)}dan ~!is.list(.). anggap ~sebagai singkatan function(.).
SlyFox

8

Berhati-hatilah dengan select()fungsinya, karena ini digunakan baik di paket dplyr dan MASS, jadi jika MASS dimuat, pilih () mungkin tidak berfungsi dengan benar. Untuk mengetahui paket apa saja yang dimuat, ketik sessionInfo()dan cari di bagian "paket terlampir lainnya:". Jika dimuat, ketik detach( "package:MASS", unload = TRUE ), dan select()fungsi Anda akan berfungsi kembali.


12
alternatifnya Anda bisa mengakses fungsi secara langsung di namespace paket seperti itu dplyr::select().
Triamus

2
Saya sudah terlalu sering mengalami masalah ini. Sekarang saya biasanya mendefinisikan fungsi baru di bagian atas skrip saya dselect <- dplyr::select().
filups21

5

Kita dapat mencoba

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

Terima kasih @akrun, ini bekerja dengan sempurna. Namun, mengingat sensasi seputar dplyrkemampuan untuk membuat tugas analisis dasar mudah dibaca dan ditulis, saya kecewa karena solusi yang sebenarnya tampak seperti solusi.
Navaneethan Santhanam

@NavaneethanSanthanam Sebenarnya, one_ofsolusi lain adalah cara untuk pergi. Saya lupa tentang itu.
akrun

3

Cara lain adalah dengan mengubah kolom yang tidak diinginkan menjadi NULL, ini menghindari tanda kurung yang disematkan:

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

Ini juga tidak memberi peringatan jika kolom tidak ada.
skoz

3

Jika Anda memiliki karakter khusus dalam nama kolom, salah satu selectatau select_mungkin tidak berfungsi seperti yang diharapkan. Properti dplyrpenggunaan ini ".". Untuk merujuk ke kumpulan data dalam pertanyaan, baris berikut dapat digunakan untuk menyelesaikan masalah ini:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

Kode hanya jawaban tidak dianjurkan. Mohon berikan beberapa penjelasan tentang bagaimana jawaban itu bekerja dan bagaimana perbedaannya dari jawaban yang sudah ada.
Ralf Stubner

Terima kasih!! Tidak ada solusi lain di atas yang berfungsi untuk alasan yang tepat ini.
Marty999

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.