2010-12-09 2 views
2

배경의도 한대로 plyr/ddply를 사용하도록이 코드를 다시 작성할 수 있습니까?

난 통계적 요약을 계산하고자하는 확률 분포의 dataframe 가지고

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

접근법

단계 1 : I는를 계산하는 함수를 작성 요약 및 반환 mean(lcl, ucl)

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 = '')) 
} 

2 단계 :

이 작업을 수행하는 적절한 방법은 무엇입니까 : 내 dataframe에 새로운 열이 stats

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

질문 1이라는 추가 하시겠습니까? 내가하려고 할 때 오류가 발생

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

질문 2 : (추가 신용)

summary.stats 기능을 코딩하는보다 효율적인 방법을 덜 '의 경우'로, 즉,이 있습니까? 날 위해를 지우는 셰인과 여호수아에

갱신

감사합니다.

나는 또한 do a plyr operation on every row of a dataframe

답변

4

하려고 다른 사람을 위해 도움이 될해야 문제를 발견 여기에 대신 switch를 사용하여 summary.stats의 청소 업 버전입니다. 또한 출력에 "stats"라는 이름을 추가했습니다. 그 이유는 당신을 걸러내는 것 같아요.

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

나는 plyr이 작업을 수행하는 방법을 잘 모르겠지만,이 같은 지루한 팔자 'sapply으로 작업을 수행 할 수 있습니다

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

내가 모르는 뭔가가 있지만, 조쉬의 기능을 사용 할 수 있으며, 귀하의 데이터,이 잘 작동합니다.

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

출력을 어떻게 표시 하시겠습니까?

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

편집

죄송합니다, 전체 코멘트를 읽을하지 않았다. 그럼이게 잘 될거야. (내 예에서는 여기에 하나의 칸을 남겨둔다.)

ddply(priors, .(distn, parama, paramb), function(x) 
    data.frame(x, stats=summaryStats(x$distn, x$parama, x$paramb))) 
+0

나는 그것이 새로운 컬럼 이름을 "stats"로 만들고 싶어한다고 생각한다. 나는 그의 기능의 나의 버전에 그것을 추가했다. –

+0

@Shane, 답변 해 주셔서 감사합니다.내가 혼란스럽게 생각하는 것은'ddply'를 어떻게 priors의 새로운 컬럼에 할당 할 수있는 하나의 컬럼을 출력 할 수 있는가하는 것입니다. 'priors $ stats <- ddply (....) $ V1'; 나는'ddply() $ V1'을 사용하는 것이 올바른 사용이라고 생각하지 않습니다. '실제''priors' 데이터 프레임에는'ddply()'에서 모두 지정할 필요없이 보유하고 싶은 다른 컬럼이 있습니다. –

+0

@David 내 코드를 실행하십시오. 'ddply' *는 자동으로 그렇게합니다. – Shane