Domanda

Sfondo

Ho un dataframe di distribuzioni di probabilità che vorrei calcolare rilevazioni statistiche per:

priors <- structure(list(name = c("theta1", "theta2", "theta3", "theta4", 
  "theta5"), distn = c("gamma", "beta", "lnorm", "weibull", "gamma"), 
   parama = c(2.68, 4, 1.35, 1.7, 2.3), paramb = c(0.084, 7.2, 0.69, 0.66, 3.9),
   another_col = structure(c(3L, 4L, 5L, 1L, 2L
   ), .Label = c("1", "2", "a", "b", "c"), class = "factor")), 
   .Names = c("name", "distn", "parama", "paramb", "another_col"), row.names = c("1",
   "2", "3", "4", "5"), class = "data.frame")

Approccio

Passaggio 1: Ho scritto una funzione per calcolare le sintesi ei mean(lcl, ucl) ritorno

 summary.stats <- function(distn, A, B) {
  if (distn == 'gamma'  ) ans <- c(A*B,                       qgamma(c(0.05, 0.95), A[ ], B))
  if (distn == 'lnorm'  ) ans <- c(exp(A + 1/2 * B^2),        qlnorm(c(0.05, 0.95), A, B))
  if (distn == 'beta'   ) ans <- c(A/(A+B),                   qbeta( c(0.05, 0.95), A, B))
  if (distn == 'weibull') ans <- c(mean(rweibull(10000,A,B)), qweibull(c(0.05, 0.95), A, B))
  if (distn == 'norm'   ) ans <- c(A,                         qnorm( c(0.05, 0.95), A, B))
  ans <- (signif(ans, 2))
  return(paste(ans[1], ' (', ans[2], ', ', ans[3],')', sep = ''))
}

Passaggio 2: vorrei aggiungere una nuova colonna alla mia dataframe chiamato stats

priors$stats <- ddply(priors, 
                     .(name, distn, parama, paramb), 
                     function(x)  summary.stats(x$distn, x$parama, x$paramb))$V1

Domanda 1:

qual è il modo corretto di fare questo? Ottengo un errore quando provo

                ddply(priors, 
                     .(name, distn, parama, paramb),
                     transform, 
                     stats = function(x)  summary.stats(x$distn, x$parama, x$paramb))

Domanda 2: (credito extra)

C'è un modo più efficiente per il codice della funzione summary.stats, vale a dire con meno 'se di'?

update

Grazie a Shane e Joshua per rimozione di questo per me.

Ho anche trovato una domanda che dovrebbe essere utile per gli altri cercando di eseguire un'operazione plyr su ogni riga di una dataframe

È stato utile?

Soluzione

Ecco una versione ripulita del vostro summary.stats che usi switch invece. Ho anche aggiunto il nome di "stats" per l'uscita, dal momento che sembra essere la cosa che inciampare.

summaryStats <- function(distn, A, B) {
  CI <- c(0.05, 0.95)
  FUN <- get(paste("q",distn,sep=""))
  ans <- switch(distn,
    gamma   = A*B,
    lnorm   = exp(A + 1/2 * B^2),
    beta    = A/(A+B),
    weibull = mean(rweibull(10000,A,B)),
    norm    = A)
  ans <- c(ans, FUN(CI, A, B))
  ans <- (signif(ans, 2))
  out <- c(stats=paste(ans[1], ' (', ans[2], ', ', ans[3],')', sep=''))
  return(out)
}

Non sono sicuro di come fare questo con plyr, ma è possibile farlo con noioso ol' sapply in questo modo:

priors$stats <- sapply(1:nrow(priors),
  function(i) with(priors[i,], summaryStats(distn, parama, paramb) ))

Altri suggerimenti

potrei mancare qualcosa, ma utilizzando la funzione di Josh ei dati, questo funziona bene.

priors <- ddply(priors, 
  .(name, distn, parama, paramb), 
  function(x)  summaryStats(x$distn, x$parama, x$paramb))
colnames(priors)[5] <- "stats"

Che cosa volete che il vostro uscita a guardare come?

> priors
    name   distn parama paramb            stats
1 theta1   gamma   2.68  0.084   0.23 (7.8, 69)
2 theta2    beta   4.00  7.200 0.36 (0.15, 0.6)
3 theta3   lnorm   1.35  0.690    4.9 (1.2, 12)
4 theta4 weibull   1.70  0.660 0.59 (0.12, 1.3)
5 theta5   gamma   2.30  3.900    9 (0.12, 1.3)

Modifica

Siamo spiacenti, non ha letto tutto il tuo commento. Quindi questo dovrebbe funzionare (nel mio esempio qui, lascio fuori una colonna):

ddply(priors, .(distn, parama, paramb), function(x) 
   data.frame(x, stats=summaryStats(x$distn, x$parama, x$paramb)))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top