Bagaimana cara mendapatkan nama grup di grup data.table?

Saya ingin menerapkan fungsi ke kolom data.tabel tetapi saya ingin memperhitungkan grup mana fungsi tersebut diterapkan, yaitu saya ingin meneruskan nilai grup sebagai parameter ke fungsi tersebut. Namun saya tidak bisa mendapatkan nama grup ketika fungsi saya diterapkan.

Bagaimana cara mendapatkan nilai grup? Atau haruskah saya menggunakan pendekatan yang berbeda?

Contoh:

library(data.table)
set.seed(369)
dta <- data.table(gr = 1:5, 
                  a = rnorm(5),  
                  b = rnorm(5),
                  c = rnorm(5),
                  d = rnorm(5))

add <- function(x, y, group){ 
  if(group == 1){
    x + y
  } else{
    x - y
  }
}

dta[, newcol := add(c, d), by = (gr)]

Saya tidak tahu cara meneruskan nilai grup saat ini ke fungsi


person Xlrv    schedule 14.03.2019    source sumber
comment
inilah tujuan dari simbol .BY di data.table   -  person MichaelChirico    schedule 14.03.2019


Jawaban (1)


Catatan1: Jawaban undian singkat saya secara keliru menyarankan penggunaan .GRP, yang kebetulan menghasilkan jawaban yang sama dalam contoh spesifik ini. Sesuai rekomendasi @MichaelChirico, .BY adalah simbol khusus yang tepat untuk digunakan.

Catatan 2: Terima kasih @Frank atas masukan tambahannya -- Saya membuat intinya di sini dari beberapa eksperimen dengan .BY, dan telah memperbarui jawabannya lagi untuk mencerminkan dengan tepat kebutuhan untuk mereferensikan kolom pengelompokan dalam daftar berdasarkan nama.

Sepertinya simbol khusus .BY adalah yang Anda cari. Untuk mempelajari lebih lanjut tentang cara kerja .BY dan simbol lainnya, jalankan help("special-symbols") di konsol untuk melihat dokumentasi.

library(data.table)

set.seed(369)
dta <- data.table(gr = 1:5, 
                  a = rnorm(5),  
                  b = rnorm(5),
                  c = rnorm(5),
                  d = rnorm(5))

add <- function(x, y, group){ 
  if(group == 1){
    x + y
  } else{
    x - y
  }
}

dta[, newcol := add(c, d, .BY$gr), by = (gr)]

print(dta)

#    gr          a           b           c            d     newcol
# 1:  1 -0.7506434  1.08042639 -0.57234502 -0.009598695 -0.5819437
# 2:  2  0.8976528 -0.45909601 -0.08179559 -1.359655922  1.2778603
# 3:  3  0.7449628 -0.92638505 -1.11577747  0.654088229 -1.7698657
# 4:  4  0.5811869 -0.07451776 -0.50771981 -1.009298251  0.5015784
# 5:  5 -0.3270194  0.97218850  0.55705663 -0.032128474  0.5891851

Catatan 3: Ini juga berfungsi dengan baik untuk sebagian besar kasus penggunaan dan mungkin sedikit lebih intuitif:

dta[, newcol := add(c, d, gr), by = (gr)]
person Matt Summersgill    schedule 14.03.2019
comment
.BY adalah sebuah daftar, tetapi berfungsi untuk kasus OP karena list(1) == 1. Anda dapat melakukan add(c, d, .BY$gr) atau lebih umum tetapi kurang mudah dibaca do.call(add, c(list(c, d), .BY)) asalkan namanya cocok. - person Frank; 14.03.2019
comment
Terima kasih @Frank -- Mengobrol dengan beberapa kasus lain dalam inti di sini Saya melihat ada lebih banyak lapisan ke bawang daripada yang saya tarik sebelumnya, dan saya mengerti apa yang Anda katakan tentang rekomendasi .BY$gr. Saya pasti akan menerima masukan lainnya untuk memastikan saya tidak menyebarkan disinformasi di sini. - person Matt Summersgill; 14.03.2019
comment
Oke terima kasih. Saya kira intinya bukanlah bahwa mereka harus direferensikan berdasarkan nama karena Anda biasanya perlu mengakses satu elemen .BY daripada daftar lengkap, misalnya, dta[, sqrt(.BY), by=gr] gagal karena Anda tidak dapat mengambil sqrt dari sebuah daftar, jadi dta[, sqrt(.BY$gr), by=gr] atau dta[, sqrt(.BY[[1]]), by=gr]. Sebenarnya bisa langsung saja merujuk ke gr dan tidak perlu melalui .BY seperti dta[, sqrt(gr), by=gr]. Maaf bila membingungkan; yang terakhir adalah rekomendasiku, kurasa. Sekarang saya bertanya-tanya mengapa OP tidak mencobanya pada awalnya :) - person Frank; 14.03.2019
comment
Ya. Saya juga mengambil langkah mundur dan menyadari bahwa dta[, sqrt(gr), by=gr] adalah cara yang mungkin saya lakukan secara normal -- sekarang saya hanya mencoba mencari tahu apakah ada kasus di mana hal itu tidak berhasil. Saya pikir ini mungkin menimbulkan beberapa masalah dengan beberapa variabel pengelompokan dan lebih banyak pengamatan per kelompok? Pastinya harus ada, kalau tidak kenapa harus ada simbol khusus .BY? - person Matt Summersgill; 15.03.2019
comment
Ada beberapa alasan saya menggunakannya: untuk membuat kode saya lebih mudah dibaca (dalam arti bahwa saya dapat melihat dengan jelas bahwa saya menggunakan variabel pengelompokan), untuk membuatnya agnostik terhadap .BY vars (misalnya, dengan toString( .BY) sebagai judul plot atau cat-ed untuk menghibur ketika j lambat sehingga saya dapat melacak kemajuannya). Berikut salah satu contohnya: franknarf1.github.io/r-tutorial/_book/tables. html (cari .BY) Selain itu, saya rasa akan berguna untuk menyampaikan argumen dalam pola do.call yang saya sebutkan. - person Frank; 15.03.2019