Loops per creare nuove variabili in ddply
Domanda
Sto usando DDPLY per aggregare e riassumere le variabili del frame di dati e sono interessato a loop attraverso l'elenco del mio frame di dati per creare le nuove variabili.
new.data <- ddply(old.data,
c("factor", "factor2"),
function(df)
c(a11_a10 = CustomFunction(df$a11_a10),
a12_a11 = CustomFunction(df$a12_a11),
a13_a12 = CustomFunction(df$a13_a12),
...
...
...))
C'è un modo per me per inserire un ciclo in DDPLY in modo da poter evitare di scrivere ogni nuova variabile di riepilogo, ad esempio
for (i in 11:n) {
paste("a", i, "_a", i - 1) = CustomFunction(..... )
}
So che non è così che sarebbe stato effettivamente fatto, ma volevo solo mostrare come lo concettualizzare. C'è un modo per farlo nella funzione che chiamo in ddply o tramite un elenco?
AGGIORNARE: Perché sono un nuovo utente, non posso pubblicare una risposta alla mia domanda:
La mia risposta prevede idee dalla risposta di Nick e dal commento di Ista:
func <- function(old.data, min, max, gap) {
varrange <- min:max
usenames <- paste("a", varrange, "_a", varrange - gap, sep="")
new.data <- ddply(old.data,
.(factor, factor2),
colwise(CustomFunction, c(usenames)))
}
Soluzione
Basandosi sull'eccellente risposta di @nick, ecco un approccio al problema
foo <- function(df){
names = paste("a", 11:n, "_a", 10:(n-1), sep = "")
results = sapply(df[,names], CustomFunction)
}
new.data = ldply(dlply(old.data, c("factor", "factor2")), foo)
Ecco un'applicazione di esempio utilizzando il tips
set di dati in ggplot2
. Supponiamo di voler calcolare la media di tip
e total_bill
per combinazione di sex
e smoker
, ecco come funzionerebbe il codice
foo = function(df){names = c("tip", "total_bill"); sapply(df[,names], mean)}
new = ldply(dlply(tips, c("sex", "smoker")), foo)
Produce l'output mostrato di seguito
.id tip total_bill
1 Female.No 2.773519 18.10519
2 Female.Yes 2.931515 17.97788
3 Male.No 3.113402 19.79124
4 Male.Yes 3.051167 22.28450
È questo quello che stavi cercando?
Altri suggerimenti
Se ti capisco correttamente, si desidera essenzialmente applicare una funzione personalizzata a ogni colonna del ddply
Data.Frame.
La buona notizia è che c'è un ddply
funzione che fa esattamente questo. Ciò significa che la soluzione al tuo problema si riduce a una fodera:
Basandosi sull'eccellente esempio di @ramnath:
library(ggplot2)
customfunction <- mean
ddply(tips, .(sex, smoker), numcolwise(customfunction))
sex smoker total_bill tip size
1 Female No 18.10519 2.773519 2.592593
2 Female Yes 17.97788 2.931515 2.242424
3 Male No 19.79124 3.113402 2.711340
4 Male Yes 22.28450 3.051167 2.500000
Il motivo per cui funziona è quello colwise
Trasforma una funzione che funziona su un vettore in una funzione che funziona su una colonna in un dati. Ci sono due varianti di colwise
: numcolwise
funziona solo su colonne numeriche e catcolwise
funziona su colonne categoriche. Vedere?colwise
per maggiori informazioni.
MODIFICARE:
Apprezzo che potresti non voler applicare la funzione a tutto colonne nel tuo data.rame. Tuttavia, trovo questa sintassi così facile, che il mio approccio generale sarebbe quello di modificare i dati. ddply
. Ad esempio, i seguenti sottogruppi di esempio modificati tips
per escludere alcune colonne. La soluzione è ancora un liner:
ddply(tips[, -2], .(sex, smoker), numcolwise(customfunction))
sex smoker total_bill size
1 Female No 18.10519 2.592593
2 Female Yes 17.97788 2.242424
3 Male No 19.79124 2.711340
4 Male Yes 22.28450 2.500000
In passaggi:
varrange<-11:n
usenames<-paste("a", varrange, "_a", varrange - 1, sep="")
results<-sapply(usenames, function(curname){CustomFunction(df[,curname])})
names(results)<-usenames
È questo che vuoi?