Birden çok çıkışa fcase

0

Soru

Aşağıdaki tabloyu varsayalım:

data <- data.table(dummy=1:10)

Aşağıdakileri yapabileceğinizi biliyorum.:

data[dummy < 5, c("test1", "test2") := list("Yes", 1)]

ve:

data[, test1 := fcase(dummy < 5, "Yes")]
data[, test2 := fcase(dummy < 5, 1)]

Bunları böyle bir araya getirmeye çalışıyorum:

data[, c("test1", "test2") := fcase(dummy < 5, list("Yes", 1))]

Ama bana şu hatayı veriyor:

Error in fcase(dummy < 5, list("Yes", 1)) : 
  Length of output value #2 must either be 1 or length of logical condition.

Birden fazla filtreden geçmem gerekiyor, bu yüzden kullanmak mantıklı fcase. Her filtre için ilk çözümü her zaman böyle kullanmaya başvurabilirim:

data[dummy < 5, c("test1", "test2") := list("Yes", 1)]
data[dummy > 7, c("test1", "test2") := list("No", 0)]
data[between(dummy, 5, 7), c("test1", "test2") := list("Maybe", NA)]

ama daha olası bir şey olup olmadığını merak ediyorum. Her bir kombinasyonla bir tablo oluşturma çözümü de vardır test1 ve test2 ve bunu yaptıktan sonra bu tabloyu veri tablosuyla birleştirin. fcase sadece için test1 öyle gibi:

tests <- data.table(test1 = c("Yes", "No", "Maybe"),
                    test2 = c(1, 0, NA))

data[, test1 := fcase(dummy < 5, "Yes",
                      dummy > 7, "No",
                      between(dummy, 5, 7), NA_character_)]
merge(data, tests, by = "test1", all.x = T, sort = F)

Ancak bu, büyük ve karmaşık bir veri tabanı için verimsiz görünüyor

case data.table r
2021-11-17 16:48:12
1

En iyi cevabı

4

İle rbindlist:

data[, c("test1", "test2") := rbindlist(fcase(dummy < 5, .(.("Yes", 1)),
                                              dummy > 7, .(.("No", 0)),
                                              default = .(.("Maybe", NA))))]
data
#>     dummy test1 test2
#>  1:     1   Yes     1
#>  2:     2   Yes     1
#>  3:     3   Yes     1
#>  4:     4   Yes     1
#>  5:     5 Maybe    NA
#>  6:     6 Maybe    NA
#>  7:     7 Maybe    NA
#>  8:     8    No     0
#>  9:     9    No     0
#> 10:    10    No     0

do.call koymana izin verecek fcase bir listedeki koşullar ve iç içe geçmiş listelerin başka bir listesindeki değerler:

data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7),
                                                             .(.(.("Yes", 1)), .(.("Maybe", NA)), .(.("No", 0))))))]

Ya da tests örnek:

tests <- data.table(test1 = c("Yes", "Maybe", "No"),
                    test2 = c(1, NA, 0))
tests[, val := .(.(.(.SD))), by = 1:nrow(tests)]
data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7), tests$val)))]
2021-11-22 13:23:13

Merhaba @jblood94, Hem zarif hem de aydınlatıcı harika bir cevap. Paylaşım için teşekkürler. Şerefe.
lovalery

Bu tam olarak ne I was seyir için. Çok teşekkür ederim
Wietse de Vries

Merhaba @jblood94, aynı şekilde, bir listedeki farklı testleri ve başka bir listedeki değerleri de koymanın bir yolu olup olmadığını biliyor musunuz? Önerdiğim sözdiziminin yanlış olduğunu bilmeme rağmen, açık olmak gerekirse, böyle bir şey yazın: rbindlist(fcase(.(dummy < 5, dummy > 7), .(.("Yes", 1)), .(.("No", 0))), default = .(.("Maybe", NA))))] . Görüşleriniz için şimdiden teşekkür ederiz. Şerefe.
lovalery

@ lovalery Soru-yorumunuzun satırlarına birkaç örnek ekledim.
jblood94

Çok teşekkür ederim @jblood94. Örneklerin sana son bir soru sormamı sağlıyor! Son örneğinizi takip ederek, aşağıdakileri ele almaya çalıştım: cases nasıl idare ettin tests ancak R aşağıdaki hata iletisini döndürür: Error in (function (..., default = NA) : Argument #1 must be logical. İşte yaptığım şey: cases <- data.table(Ncases = c("dummy < 5", "dummy <= 7", "dummy > 7")), sonraları cases[, val := .(.(.(. SD))), by = 1:nrow(cases)] ve son olarak data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(as.list(cases$val)), as.list(tests$val))))] Yardımlarınız için şimdiden teşekkür ederim. Şerefe.
lovalery

@sevgiler fcase için dizeleri kabul etmez when değişkenler. Etrafta yaparak çalışabilirsin Ncases bir ifade vektörü. Bu, operasyonun sorusuyla uyuşmuyor, bu yüzden cevabımı daha fazla karıştırmamayı tercih ederim. Yeni bir soru oluşturmayı ve buna atıfta bulunmayı öneriyorum - belki birileri düşündüğümden daha iyi bir yol bulacaktır.
jblood94

Tamam, yorumunuz için @jblood94'e çok teşekkür ederim. Bana verdiğin yolu keşfetmeye çalışacağım ve eğer başarısız olursam (ki bu çok muhtemel!), Önerdiğiniz gibi, buna bir bağlantı içeren yeni bir soru yayınlayacağım. Şerefe.
lovalery

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................