【问题标题】:Groupby + summarise on multicolumns with subseted rows in RGroup By +汇总在R中具有子集行的多列
【发布时间】:2022-01-15 19:07:42
【问题描述】:

我正在尝试找出一个干净的tidy 表达式,以使用group_bysummarise 的子集行聚合多列的统计信息。下面是一个用循环解决的例子。

# example data
dat <- data.frame(
  method = rep(c("A", "B", "baseline"), 2),
  id = rep(1:2, each = 3),
  X = round(rnorm(6, 1, 0.2),3),
  Y = round(runif(6, 1, 2),3)
)
print(dat)
#>     method id     X     Y
#> 1        A  1 0.859 1.003
#> 2        B  1 0.993 1.922
#> 3 baseline  1 1.401 1.959
#> 4        A  2 1.084 1.432
#> 5        B  2 1.083 1.883
#> 6 baseline  2 0.943 1.341

我们以ABbaseline为方法名,XY为评价标准,id为重复实验的ID。然后,我们想弄清楚方法 A 和方法 B 在XY 的意义上得到了多少改进。改进是通过评估标准相对于基线方法的相对收缩来衡量的。

result <- dat[0,]
for (i in unique(dat$id)) {
  score_A <- dat[dat$id == i & dat$method == "A", c("X", "Y")]
  score_B <- dat[dat$id == i & dat$method == "B", c("X", "Y")]
  score_baseline <- dat[dat$id == i & dat$method == "baseline", c("X", "Y")]
  
  result <- rbind(
    result,
    cbind(
      data.frame(method = c("A", "B")),
      rbind(
        (score_baseline - score_A) / score_baseline,
        (score_baseline - score_B) / score_baseline
      )
    )
  )
}
print(result)
#>    method          X           Y
#> 3       A  0.3868665  0.48800408
#> 31      B  0.2912206  0.01888719
#> 6       A -0.1495228 -0.06785981
#> 61      B -0.1484624 -0.40417599

现在,我想要一个针对上述结果的更多 tidy 解决方案。

【问题讨论】:

    标签: r dataframe tidyverse tidyr


    【解决方案1】:

    使用across 你可以这样做:

    注意:使用随机数据时,您应该使用set.seed。因此,我的随机数据与您提供的数据不同。

    library(dplyr)
    
    dat %>%
      group_by(id) %>%
      mutate(across(c(X, Y), ~ (.x[method == "baseline"] - .x) / .x[method == "baseline"])) %>%
      ungroup() %>%
      filter(!method == "baseline")
    #> # A tibble: 4 × 4
    #>   method    id     X      Y
    #>   <chr>  <int> <dbl>  <dbl>
    #> 1 A          1 0.323 -0.521
    #> 2 B          1 0.273 -0.426
    #> 3 A          2 0.245 -0.823
    #> 4 B          2 0.236 -0.196
    

    数据

    set.seed(123)
    
    dat <- data.frame(
      method = rep(c("A", "B", "baseline"), 2),
      id = rep(1:2, each = 3),
      X = round(rnorm(6, 1, 0.2), 3),
      Y = round(runif(6, 1, 2), 3)
    )
    

    【讨论】:

      猜你喜欢
      • 2019-11-26
      • 1970-01-01
      • 2014-11-03
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-19
      • 1970-01-01
      相关资源
      最近更新 更多