【问题标题】:Compute new variable based on multiple arguments in subsets of dataframe基于数据帧子集中的多个参数计算新变量
【发布时间】:2021-05-14 19:04:01
【问题描述】:

我正在使用一个大型数据库,该数据库包含超过 100.000 行的多项研究。研究规模从 300 到超过 10.000 不等,并且会定期添加更多研究。

我想为每项研究计算 h1 和 h2 的参考区间,不包括不符合标准的案例。之后,我想计算超出这些参考范围的案例,但这次使用所有案例。我想每次研究都这样做,最好是循环或按研究拆分,因为会定期添加新的研究。这样我就不必每次添加新研究时都更改代码。

我尝试了 for 循环和 group_by(),但不幸的是两者都不起作用。

考虑这个data.frame:

df <- data.frame(study = rep(LETTERS[1:3], each = 4), 
                 h1 = c(2, 3, 8, 4, 5, 8, 1, 6, 7, 8, NA, 11), 
                 h2 = c(10, 12, 9, 14, 15, 16, 20, 19, 11, 12, 14, 18),
                 v1 = c(0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1), 
                 v2 = c(0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0))
df

# Groups:   study [3]
   study    h1    h2    v1    v2
   <chr> <dbl> <dbl> <dbl> <dbl>
 1 A         2    10     0     0
 2 A         3    12     0     1
 3 A         8     9     1     0
 4 A         4    14     0     0
 5 B         5    15     0     0
 6 B         8    16     0     0
 7 B         1    20     1     1
 8 B         6    19     0     0
 9 C         7    11     0     0
10 C         8    12     0     0
11 C        NA    14     0     0
12 C        11    18     1     0

我想计算每项研究的参考区间,不包括 v1 或 v2 为“1”的案例。以第一个研究为例:

   > quantile(df$h1[df$study == "A" & df$v1 == 0 & df$v2 == 0], prob = c(0.05, 0.95), na.rm = TRUE)
     5% 95% 
    2.1 3.9 
   > quantile(df$h2[df$study == "A" & df$v1 == 0 & df$v2 == 0], prob = c(0.05, 0.95), na.rm = TRUE)
      5%  95% 
    10.2 13.8

现在我想计算一个新变量,如果 h1 >= 参考区间 q1 的上限且 h2

我试过这个for循环:

library(dplyr)    
for (i in levels(df$study)){
      
      q1 <- quantile(df$h1[df$study == i & df$v1 == 0 & df$v2 == 0], prob = c(0.05, 0.95), na.rm = TRUE)
      q2 <- quantile(df$h2[df$study == i & df$v1 == 0 & df$v2 == 0], prob = c(0.05, 0.95), na.rm = TRUE)
      
      df <- df %>% 
        mutate(x1 = if_else(study == i & h1 >= q1[2] & h2 < q2[1], 1, 0))  
    }

不幸的是,这不起作用。此外,如果它可以工作,我认为它会导致一个循环,它会覆盖它自己的结果。我也尝试过使用 dplyr 和 group_by;

df <- df %>% group_by(study)
  mutate(x1 = ifelse((df$h1 >= quantile(df$h1[df$v1 == 0 & df$v2 == 0], prob = c(0.95), na.rm = TRUE) &
                      df$h2 <  quantile(df$h2[df$v1 == 0 & df$v2 == 0], prob = c(0.05), na.rm = TRUE)), 1, 0))

但这给了我一个错误:没有适用于“变异”的方法应用于类“c('double','numeric')”的对象。

它应该会产生一个新的变量x1,第一个研究应该是0,0,1,0。有没有人有提示必须解决这个问题?

【问题讨论】:

    标签: r database


    【解决方案1】:

    由于您只想要h1 的上分位数和h2 的下一个分位数,因此只计算这些并将它们添加为新列进行比较。

    library(dplyr)
    
    df %>%
      group_by(study) %>%
      mutate(val1 = quantile(h1[v1 == 0 & v2 == 0], prob = 0.95, na.rm = TRUE), 
             val2 = quantile(h2[v1 == 0 & v2 == 0], prob = 0.05, na.rm = TRUE),
             x1 = as.integer(h1 >= val1 & h2 <= val2), 
             x1 = replace(x1, is.na(h1) | is.na(h2), NA)) %>%
      ungroup -> df
    df
    
    #   study    h1    h2    v1    v2  val1  val2    x1
    #   <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
    # 1 A         2    10     0     0  3.9   10.2     0
    # 2 A         3    12     0     1  3.9   10.2     0
    # 3 A         8     9     1     0  3.9   10.2     1
    # 4 A         4    14     0     0  3.9   10.2     0
    # 5 B         5    15     0     0  7.8   15.1     0
    # 6 B         8    16     0     0  7.8   15.1     0
    # 7 B         1    20     1     1  7.8   15.1     0
    # 8 B         6    19     0     0  7.8   15.1     0
    # 9 C         7    11     0     0  7.95  11.1     0
    #10 C         8    12     0     0  7.95  11.1     0
    #11 C        NA    14     0     0  7.95  11.1    NA
    #12 C        11    18     1     0  7.95  11.1     0
    

    【讨论】:

    • 谢谢 Ronak Shah,这个解决方案确实解决了我的一些问题,只是 x1 的计算不考虑数据集中的 NA,导致第 11 行为 0。我似乎找不到解决此问题的简单方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 2020-03-24
    相关资源
    最近更新 更多