具有控制组或基线组的数据框中的 R 计算

R calculation in a dataframe with a control or baseline group

我有一个数据框 df,其中包含来自 2 个站点 (A&B)、2 个组 (group1&2) 的 3 种不同方法(method1、method2、method0)的估计值:

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

我想使用 method0 作为基线组,并计算每个估计的相对百分比偏差 (rb) site/group。

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

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

并且每个 site/group 中只有一个 estimate0。我试图编写一个简单的函数并为每个 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")

非常感谢任何输入和评论。

这可能不是最优雅的。我只是个黑客。但我认为它可以满足您的需求。

> 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

此数据集将包含您的所有 baseline/control 值。 下一段代码将它合并回您的初始数据框并创建您想要的变量。然后,如果需要,您可以删除 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

我知道有一些方法可能更有效,但我仍然是菜鸟。

这是您尝试执行的一种简单且更优雅的方法。

首先,简化你的函数(如果你打算在管道中使用它,它不需要将整个 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))