I recently eseguito nella seguente operazione raggruppata: per ogni gruppo, i valori vengono assegnati con numeri distribuiti uniformemente tra -0,5 e 0,5 e se il gruppo ha un solo elemento allora è assegnato il valore 0. Per esempio, se ho avuto i seguenti gruppi osservati:Assegnare valori per gruppo quando tutto ciò che conta è il numero di membri del gruppo
g <- c("A", "A", "B", "B", "A", "C")
valori poi mi aspetterei assegnati:
outcome <- c(-0.5, 0, -0.5, 0.5, 0.5, 0)
le tre osservazioni nel gruppo a sono stati assegnati valori -0.5 , 0 e 0.5 (in ordine), i due osservano nel gruppo B sono stati assegnati valori -0.5 e 0.5 (in ordine) e l'osservazione nel gruppo C è stata assegnata al valore 0.
Normalmente quando eseguo un'operazione raggruppata su un vettore per ottenere un altro vettore, utilizzo il Funzione ave
, con il modulo ave(data.vector, group.vector, FUN=function.to.apply.to.each.groups.data.vector.subset)
. Tuttavia in questa operazione tutto quello che devo sapere è il numero di membri nel gruppo, quindi non c'è lo data.vector
. Di conseguenza, ho finito solo facendo un vettore di dati che ho ignorato nella mia chiamata a ave
:
ave(rep(NA, length(g)), g, FUN=function(x) {
if (length(x) == 1) {
return(0)
} else {
return(seq(-0.5, 0.5, length=length(x)))
}
})
# [1] -0.5 0.0 -0.5 0.5 0.5 0.0
Mentre questo mi dà la risposta corretta, è ovviamente piuttosto insoddisfacente per bisogno di fare un vettore di dati che Allora ignoro. C'è un modo migliore per assegnare i valori per gruppo quando tutto ciò che conta è il numero di elementi nel gruppo?
Con 'data.table' (o simile con' dplyr') si potrebbe fare 'as.data.table (g) [, res: = if (.N> 1) seq (-0.5, 0.5, length = .N) else 0, by = g] $ res' anche se non è sicuro se questo è meglio. –
btw, è possibile eseguire 'g' su se stesso all'interno di' ave' e non è necessario creare un nuovo vettore, ad esempio 'as.numeric (ave (g, g, FUN = function (x) { if (lunghezza (x) == 1) { ritorno (0) } else { ritorno (ss (-0.5, 0.5, lunghezza = lunghezza (x))) }} )) ' –
si potrebbe evitare il' se '' else' con 'ave (seq_along (g), g, FUN = function (x) seq (-0.5, 0.5, length = length (x)) * (length (x)! = 1) + 0L)' oppure 'library (dplyr); as.data.frame (g)%>% group_by (g)%>% mutate (val = seq (-0.5, 0.5, length = n()) * (n()! = 1) + 0L) ' – akrun