R data.simbol dan operator meja yang anda harus tahu

R data.kod meja menjadi lebih cekap - dan elegan - apabila anda memanfaatkan simbol dan fungsinya yang istimewa. Dengan ini, kami akan melihat beberapa kaedah khas untuk menyusun, mengira, dan membuat lajur baru.

Untuk demo ini, saya akan menggunakan data dari tinjauan pembangun Stack Overflow 2019, dengan kira-kira 90,000 respons. Sekiranya anda ingin mengikuti, anda boleh memuat turun data dari Stack Overflow.

Sekiranya pakej data.table tidak dipasang pada sistem anda, pasangkannya dari CRAN dan kemudian muatkan seperti biasa dengan library(data.table). Untuk memulakan, anda mungkin ingin membaca hanya beberapa baris pertama set data untuk mempermudah pemeriksaan struktur data. Anda boleh melakukannya dengan fread()fungsi data.table dan nrowsargumen. Saya akan membaca dalam 10 baris:

data_sampel <- fread ("data / survey_results_public.csv", nrows = 10)

Seperti yang akan anda lihat, terdapat 85 lajur untuk diperiksa. (Sekiranya anda ingin mengetahui maksud semua lajur, terdapat fail dalam muat turun dengan skema data dan PDF tinjauan asal.) 

Untuk membaca semua data, saya akan menggunakan:

mydt <- fread ("data / survey_results_public.csv")

Seterusnya, saya akan membuat data baru. Meja dengan hanya beberapa lajur untuk memudahkan kerja dan melihat hasilnya. Peringatan bahawa data.table menggunakan sintaks asas ini: 

mydt [i, j, oleh]

Pengenalan pakej data.table mengatakan untuk membaca ini sebagai "ambil dt, subset atau susun semula baris menggunakan i, hitung j, dikelompokkan oleh." Perlu diingat bahawa i dan j serupa dengan susunan pendakap asas R: baris pertama, lajur kedua. Jadi saya adalah untuk operasi yang anda lakukan pada baris (memilih baris berdasarkan nombor baris atau keadaan); j adalah apa yang akan anda lakukan dengan lajur (pilih lajur atau buat lajur baru dari pengiraan). Walau bagaimanapun, perhatikan juga bahawa anda boleh melakukan lebih banyak pendakap meja dalam data daripada kerangka data R asas. Dan bahagian "oleh" baru untuk data.table.

Oleh kerana saya memilih lajur, kod itu masuk di tempat "j", yang bermaksud tanda kurung memerlukan koma terlebih dahulu untuk membiarkan tempat "i" kosong:

mydt [, j]

Pilih lajur data.tabel

Salah satu perkara yang saya suka mengenai data.table adalah mudah memilih lajur sama ada dipetik atau tidak disebut . Tidak disebut harga adalah lebih mudah (yang biasanya cara tidyverse itu). Tetapi dikutip berguna jika anda menggunakan data. Meja di dalam fungsi anda sendiri, atau jika anda ingin memasukkan vektor yang anda buat di tempat lain dalam kod anda.

Anda boleh memilih lajur data.tabel dengan cara asas R biasa, dengan vektor konvensional yang disebut dengan nama lajur. Sebagai contoh: 

dt1 <- mydt [, c ("LanguageWorkedWith", "LanguageDesireNextYear",

"OpenSourcer", "CurrencySymbol", "ConvertedComp",

"Hobi")]

Sekiranya anda ingin menggunakannya tanpa tanda kutip, buat senarai bukannya vektor dan anda boleh memasukkan nama yang tidak disebut. 

dt1 <- mydt [, senarai (LanguageWorkedWith, LanguageDesireNextYear,

OpenSourcer, CurrencySymbol, ConvertedComp,

Hobi)]

Dan sekarang kita sampai pada simbol khas pertama kita. Daripada menaip list(), anda hanya boleh menggunakan titik:

dt1 <- mydt [,. (LanguageWorkedWith, LanguageDesireNextYear,

OpenSourcer, CurrencySymbol, ConvertedComp,

Hobi)]

Itu .()adalah jalan pintas untuk list()kurungan data. Tabel.

Bagaimana jika anda ingin menggunakan vektor nama lajur yang sudah ada? Meletakkan nama objek vektor ke dalam data. Kurungan meja tidak akan berfungsi. Sekiranya saya membuat vektor dengan nama lajur yang disebut, seperti: 

mycols <- c ("LanguageWorkedWith", "LanguageDesireNextYear",

"OpenSourcer", "CurrencySymbol", "ConvertedComp", "Hobbyist")

Maka kod ini tidak akan  berfungsi: 

dt1 <- mydt [, mycols]

Sebaliknya, anda perlu meletakkan .. (itu dua titik) di hadapan nama objek vektor:

dt1 <- mydt [, ..mycols]

Mengapa dua titik? Itu nampaknya tidak biasa bagi saya sehingga saya membaca penjelasannya. Fikirkan seperti dua titik dalam terminal baris perintah Unix yang menggerakkan anda satu direktori. Di sini, anda menaikkan satu ruang nama , dari persekitaran di dalam data. Kurungan meja hingga persekitaran global. (Itu sangat membantu saya mengingatnya!)

Kira data. Baris jadual

Ke simbol seterusnya. Untuk mengira mengikut kumpulan, anda boleh menggunakan .Nsimbol data.table , yang  .Nbermaksud "bilangan baris". Jumlah ini boleh menjadi jumlah baris, atau jumlah baris per kumpulan jika anda mengumpulkan di bahagian "oleh". 

Ungkapan ini mengembalikan jumlah baris dalam data.tabel: 

mydt [, .N]

Contoh berikut mengira bilangan baris yang dikelompokkan oleh satu pemboleh ubah: sama ada orang dalam tinjauan juga memberi kod sebagai hobi ( Hobbyistpemboleh ubah).

mydt [, .N, Hobi]

# pulangan:

Hobi N 1: Ya 71257 2: Tidak 17626

Anda boleh menggunakan nama lajur biasa dalam kurungan data.tabel jika hanya ada satu pemboleh ubah. Sekiranya anda ingin mengelompokkan dengan dua atau lebih pemboleh ubah, gunakan .simbol. Sebagai contoh:

mydt [, .N,. (Hobi, OpenSourcer)]

Untuk memesan hasil dari tertinggi ke terendah, anda boleh menambahkan set kurungan kedua selepas yang pertama. The .Nsimbol secara automatik menjana lajur bernama N (sudah tentu anda boleh menamakan semula jika anda mahu), jadi pesanan dengan jumlah baris boleh melihat sesuatu seperti ini:

mydt [, .N,. (Hobi, OpenSourcer)] [pesanan (Hobi, -N)]

Semasa saya belajar kod data.table, saya dapat membacanya selangkah demi selangkah. Oleh itu, saya membaca ini sebagai "Untuk semua baris di mydt (kerana tidak ada di tempat" I "), hitung bilangan baris, dikumpulkan oleh Hobbyist dan OpenSourcer. Kemudian pesan terlebih dahulu oleh Hobbyist dan kemudian bilangan baris menurun. " 

Itu setara dengan kod dplyr ini:

mydf%>%

kiraan (Hobi, OpenSourcer)%>%

pesanan (Hobi, -n)

Sekiranya anda mendapati pendekatan berbilang baris konvensional tidyverse lebih mudah dibaca, kod data.tabel ini juga berfungsi:

mydt [, .N,

. (Hobi, OpenSourcer)] [

pesanan (Hobi, -N)

]

Tambahkan lajur ke jadual data

Seterusnya, saya ingin menambahkan lajur untuk melihat apakah setiap responden menggunakan R, jika mereka menggunakan Python, jika mereka menggunakan kedua-duanya, atau jika mereka tidak menggunakan kedua-duanya. The LanguageWorkedWithlajur mempunyai maklumat mengenai bahasa yang digunakan, dan beberapa baris data yang kelihatan seperti ini:

Sharon Machlis

Setiap jawapan adalah rentetan watak tunggal. Sebilangan besar mempunyai pelbagai bahasa yang dipisahkan dengan titik koma.

Seperti yang sering terjadi, lebih mudah untuk mencari Python daripada R, kerana anda tidak boleh hanya mencari "R" dalam rentetan (Ruby dan Rust juga mengandung modal R) dengan cara anda dapat mencari "Python". Ini adalah kod yang lebih mudah untuk membuat vektor BENAR / SALAH yang memeriksa sama ada setiap rentetan di LanguageWorkedWithdalamnya mengandungi Python:

ifelse (LanguageWorkedWith% like% "Python", BENAR, SALAH)

Sekiranya anda mengetahui SQL, anda akan mengenali sintaks "suka" itu. Saya, seperti, %like%. Ini adalah kaedah yang baik untuk memeriksa pemadanan corak. Dokumentasi fungsi mengatakan bahawa ia dimaksudkan untuk digunakan di dalam kurungan tabel data, tetapi sebenarnya anda boleh menggunakannya dalam mana-mana kod anda, bukan hanya dengan data.table. Saya memeriksa dengan pembuat data.tatre Matt Dowle, yang mengatakan nasihat untuk menggunakannya di dalam kurungan adalah kerana beberapa pengoptimuman prestasi tambahan berlaku di sana.

Seterusnya, inilah kod untuk menambahkan lajur yang dipanggil PythonUser ke data.tabel:

dt1 [, PythonUser: = ifelse (LanguageWorkedWith% like% "Python", BENAR, SALAH)]

Perhatikan :=pengendali. Python juga mempunyai operator seperti itu, dan sejak saya mendengarnya disebut "operator walrus," itulah yang saya namakan. Saya fikir ia secara rasmi "tugas dengan rujukan." Ini kerana kod di atas mengubah objek dt1 objek yang ada. Meja dengan menambahkan lajur baru - tanpa perlu menyimpannya ke pemboleh ubah baru .

Untuk mencari R, saya akan menggunakan ungkapan biasa "\\bR\\b"yang mengatakan: "Cari corak yang dimulai dengan batas kata - the \\b, kemudian an R, dan kemudian diakhiri dengan batas kata yang lain. (Saya tidak boleh mencari "R;" kerana item terakhir dalam setiap rentetan tidak mempunyai titik koma.) 

Ini menambahkan lajur RUser ke dt1:

dt1 [, RUser: = ifelse (LanguageWorkedWith% like% "\\ bR \\ b", BENAR, SALAH)]

Sekiranya anda ingin menambahkan kedua lajur sekaligus, :=anda perlu mengubah operator walrus itu menjadi fungsi dengan memberi tanda petikan, seperti ini:

dt1 [, `: =` (

PythonUser = ifelse (LanguageWorkedWith% like% "Python", TRUE, FALSE),

RUser = ifelse (LanguageWorkedWith% like% "\\ bR \\ b", BENAR, SALAH)

)]

Pengendali meja data yang lebih berguna

Terdapat beberapa pengendali data.tabel lain yang perlu diketahui. The  %between% operator mempunyai sintaks ini:

myvector% antara% c (nilai_ rendah, nilai_ atas)

Oleh itu, jika saya ingin menyaring semua respons yang mana pampasan antara 50,000 hingga 100,000 dibayar dalam dolar AS, kod ini berfungsi:

comp_50_100k <- dt1 [CurrencySymbol == "USD" &

ConvertedComp% antara% c (50000, 100000)]

Garis kedua di atas adalah antara keadaan. Perhatikan bahawa %between%pengendali merangkumi kedua-dua nilai yang lebih rendah dan atas ketika memeriksa.

Pengendali lain yang berguna adalah %chin%. Ia berfungsi seperti base R's %in%tetapi dioptimumkan untuk kelajuan dan hanya untuk vektor watak . Jadi, jika saya ingin menapis untuk semua baris di mana ruangan OpenSourcer adalah "Tidak Pernah" atau "Kurang dari sekali setahun" kod ini berfungsi:

rareos <- dt1 [OpenSourcer% chin% c ("Tidak pernah", "Kurang dari sekali setahun")]

Ini hampir sama dengan asas R, kecuali asas R mesti menentukan nama bingkai data di dalam pendakap dan juga memerlukan koma selepas ungkapan penapis:

rareos_df <- df1 [df1 $ OpenSourcer% dalam% c ("Tidak Pernah", "Kurang dari sekali setahun"),]

Fungsi baru ()

Untuk demo terakhir ini, saya akan mulakan dengan membuat data baru. Meja dengan hanya orang yang melaporkan pampasan dalam dolar AS:

usd <- dt1 [CurrencySymbol == "USD" &! is.na (ConvertedComp)]

Seterusnya, saya akan membuat lajur baru yang dipanggil Languagesama ada seseorang menggunakan hanya R, hanya Python, keduanya, atau tidak. Dan saya akan menggunakan fcase()fungsi baru . Pada masa artikel ini diterbitkan, fcase()hanya tersedia dalam versi pengembangan data.table. Sekiranya anda sudah memasang data.table, anda boleh mengemas kini ke versi dev terkini dengan arahan ini: 

data.table :: update.dev.pkg ()

Fungsi fcase () mirip dengan CASE WHENpernyataan SQL dan case_when()fungsi dplyr . Sintaks asasnya  fcase(condition1, "value1", condition2, "value2")dan sebagainya. Nilai lalai untuk "semua yang lain" dapat ditambah dengan default = value.

Berikut adalah kod untuk membuat lajur Bahasa baru:

usd [, Bahasa: = fcase (

RUser &! PythonUser, "R",

PythonUser &! RUser, "Python",

PythonUser & RUser, "Keduanya",

! PythonUser &! RUser, "Ni"

)]

Saya meletakkan setiap syarat pada baris yang terpisah kerana saya lebih senang membaca, tetapi anda tidak perlu.

Perhatian: Sekiranya anda menggunakan RStudio, struktur data.table tidak akan dikemas kini secara automatik di panel RStudio kanan atas setelah anda membuat lajur baru dengan operator walrus. Anda perlu mengklik ikon muat semula secara manual untuk melihat perubahan dalam jumlah lajur.

Terdapat beberapa simbol lain yang tidak akan saya lampirkan dalam artikel ini. Anda boleh mendapatkan senarai di dalam fail bantuan "simbol khas". Jadual bantuan dengan menjalankan help("special-symbols"). Salah satu yang paling berguna, .SD, sudah mempunyai artikel dan video Do More With R sendiri, "Cara menggunakan .SD dalam pakej data R tabel."

Untuk lebih banyak petua R, buka halaman "Lakukan Lebih Banyak Dengan R" di atau lihat senarai main YouTube "Lakukan Lebih Banyak Dengan R".