2016-10-25 2 views
1

3 가지 방법 (method1, method2, method0)을 사용하여 2 개의 사이트 (A & B), 2 개의 그룹 (그룹 1 & 2)의 추정치를 포함하는 데이터 프레임 df가 있습니다.컨트롤 또는 기준 그룹이있는 데이터 프레임에서 R 계산

df1<-data.frame(site=rep("A", 21), 
       group=rep("group1", 21), 
       estimate=c(rnorm(10, 15, 3), rnorm(10, 2, 7), rnorm(1, 6, 2)), 
       method=c(rep(c("method1","method2"),each=10),"method0")) 

df2<-data.frame(site=rep("B", 21), 
       group=rep("group2", 21), 
       estimate=c(rnorm(10, 13, 3), rnorm(10, 5, 7), rnorm(1, 9, 2)), 
       method=c(rep(c("method1","method2"),each=10),"method0")) 
df<-rbind(df1, df2) 
df 
    site group estimate method 
1  A group1 15.1561073 method1 
2  A group1 14.4067422 method1 
3  A group1 12.7428921 method1 
.......... 

41 B group2 0.3548033 method2 
42 B group2 10.5820482 method0 

I 기준선 그룹으로 method0를 사용하여 각 사이트/그룹에 대한 각각의 추정 상대 백분율 편차 (RB)을 계산하고 싶다.

#for each site and group of estimate 
rb<-(estimate-estimate0)/estimate0*100% 

# where estimate0 is the estimate of method0 of that certain site/group 

각 사이트/그룹에는 하나만 추정됩니다. 나는 간단한 함수를 작성하고 각 사이트/그룹에 apply을 사용하려고했지만 제대로 작동하지 않았습니다.

fun.rb<-function(df, basline){ 
    control<-df$method==baseline 
    rb<-(df$estimate-control$estimate)/(control$estimate)*100% 
    return(rb) 
}  
df %>% group_by(site,group) %>% mutate(rb=fun.rb, baseline="method0") 

모든 입력과 의견은 크게 감사하겠습니다.

답변

1

당신이하려는 일에 대해 간단하고 우아한 방법이 있습니다.

첫째, (your'e 파이프으로 그것을 사용하게 될 것이다 경우, 그것은 인수로 전체 DF를 취할 필요가 없습니다) 함수를 단순화 :

fun.rb <- function(estimate, baseline){ 
    (estimate-baseline)/(baseline)*100 
}  

을 이제 모든 필요한 해야 할 일은 기저 열을 작성한 다음 각 행에 대한 함수를 호출하여 예상 열과 기저 열을 함수에 전달하는 것입니다.

df <- df %>% 
    group_by(site,group) %>% 
    mutate(baseline = estimate[method=="method0"], rb = fun.rb(estimate, baseline)) 
+0

와우, 좋아 보인다. 내 기능 수정에 감사드립니다. – lamushidi

+0

필자는 실제로 함수가 필요 없다는 것을 지적해야하며 함수 호출을 함수 내부의 계산으로 바꾸면 전체를 인라인으로 처리 할 수 ​​있습니다. – yeedle

+0

물론입니다. 그러면 코드가 더 깔끔해질 것입니다. 고마워. – lamushidi

1

가장 우아하지 않을 수 있습니다. 나는 단지 해킹 일 뿐이다. 그러나 나는 그것이 당신이 원하는대로한다고 생각합니다.

> library(dplyr) 
> newdf <- df %>% filter(method=="method0") %>% 
+ rename(method0_value = estimate) %>% 
+ select(-method) 
> head(newdf) 
    site group method0_value 
1 A group1  2.529237 
2 B group2  7.863411 

이 데이터 세트는 모든 기준/제어 값을 포함한다. 다음 코드는 다시 초기 데이터 프레임과 병합하여 원하는 변수를 만듭니다. 원하는 경우 method0_value를 제거 할 수 있습니다. 좋은 수표 야.

> finaldf <- left_join(df,newdf,by=c("site","group")) %>% 
+ mutate(rb= (estimate/method0_value)*100) 
> head(finaldf) 
    site group estimate method method0_value  rb 
1 A group1 8.928171 method1  2.529237 352.9986 
2 A group1 11.171023 method1  2.529237 441.6757 
3 A group1 10.790150 method1  2.529237 426.6169 
4 A group1 8.990635 method1  2.529237 355.4683 
5 A group1 14.813661 method1  2.529237 585.6969 
6 A group1 14.518803 method1  2.529237 574.0390 

이 작업을 수행하는 방법이 더 효율적이라고 알고 있습니다. 그러나 나는 여전히 멍청한 행동입니다.

+0

감사합니다. 아주 직관적인데 실제로는 두 줄의 코드 만 필요합니다. 게다가 훌륭한 함수를 작성할 필요가 없습니다. – lamushidi

관련 문제