Fcase a più uscite

0

Domanda

Assume la seguente tabella:

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

So che si possono fare le seguenti cose:

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

e:

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

Sto cercando di combinare questi in questo modo:

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

Ma mi dà il seguente errore:

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

Ho bisogno di passare attraverso filtri multipli, quindi ha senso per l'uso fcase. Posso sempre ricorrere a usare la prima soluzione per ogni tipo di filtro, in questo modo:

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)]

ma mi chiedo se non c'è qualcosa di più possibile. C'è anche la soluzione della creazione di una tabella con ogni combinazione di test1 e test2 e unire la tabella con i dati della tabella dopo aver fatto un fcase solo per test1 in questo modo:

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)

Ma questo sembra controproducente per un grande e complesso datatable

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

Migliore risposta

4

Con 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 vi permetterà di mettere il vostro fcase condizioni in un elenco e i valori di un altro elenco di liste annidate:

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

O con il tests esempio:

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

Ciao @jblood94, Grande risposta, elegante e illuminante. Grazie per la condivisione. Ciao.
lovalery

Questo è esattamente quello che stavo cercando! Vi ringrazio molto
Wietse de Vries

Ciao @jblood94, nella stessa vena, sapete se c'è un modo per mettere anche i vari test in un elenco e i valori di un altro elenco. Anche se so che la sintassi sto proponendo è sbagliato, per essere chiari, scrivere qualcosa di simile a questo: rbindlist(fcase(.(dummy < 5, dummy > 7), .(.("Yes", 1)), .(.("No", 0))), default = .(.("Maybe", NA))))] . Vi ringrazio in anticipo per i vostri commenti. Ciao.
lovalery

@lovalery ho aggiunto un paio di esempi lungo le linee della tua domanda-commento.
jblood94

Grazie mille @jblood94. I tuoi esempi mi portano a chiedere un'ultima domanda! Seguendo il tuo ultimo esempio, ho cercato di gestire la cases come hai gestito il tests ma R restituisce il seguente messaggio di errore: Error in (function (..., default = NA) : Argument #1 must be logical. Ecco cosa ho fatto: cases <- data.table(Ncases = c("dummy < 5", "dummy <= 7", "dummy > 7"))poi cases[, val := .(.(.(. SD))), by = 1:nrow(cases)] e, infine, data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(as.list(cases$val)), as.list(tests$val))))] Vi ringrazio in anticipo per il vostro aiuto. Ciao.
lovalery

@lovalery fcase non accetta le stringhe per il when gli argomenti. Si potrebbe aggirare il problema facendo Ncases un vettore di espressione. Questo non si adatta con il por domanda, quindi preferirei non ingombrare la mia risposta. Suggerisco di creare una nuova domanda e di fare riferimento a questo-forse qualcuno riuscirà a venire con un modo migliore rispetto a quello che sto pensando.
jblood94

O. K. ti Ringrazio molto @jblood94 per il tuo commento. Cercherò di esplorare il percorso per dare a me e se io non (che è molto probabile!), Vi posto una nuova domanda con un link a questo, come suggerisci tu. Ciao.
lovalery

In altre lingue

Questa pagina è in altre lingue

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