【问题标题】:Count and average of observations of multiple columns by Group ID which satisfy a condition按组 ID 对满足条件的多个列的观察计数和平均值
【发布时间】:2020-08-11 13:22:32
【问题描述】:

我在 R 中遇到了一个问题,我在下面进行了描述。我需要满足条件的每个组 ID 的所有列(避免 NA)的计数和平均值。

我有下面的数据集,其中还有一列。 “T”

    structure(list(ID = c(1L, 1L, 1L, 2L, 3L, 3L), S1 = c(NA, 5L, 
1L, 2L, 4L, 2L), S2 = c(1L, 2L, 3L, 7L, NA, 11L), T = c(3L, 3L, 
3L, 5L, 2L, 2L)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6"))

是否只有当列满足条件(列值

生成的数据框应如下所示:

  ID S1.count S2.count S1.overall S2.overall S1.per S2.per
1 1  1        3        2          3          0.5    1.0  
2 2  1        0        1          1          1.0    0.0
3 3  1        0        2          1          0.5    0.0

S1.count & S2.count : 分别小于 T 的观察数。

S1.overall & S2.overall:每列中的观察总数(避免 NA)。

S1.per & S2.per: S1.count/S1.overall , S2.count/S2.overall.

【问题讨论】:

  • 到目前为止你尝试过什么代码?

标签: r dplyr


【解决方案1】:

您可以使用aggregate() 函数来获取有关特定值出现的信息,给定一个组。将您的数据分组到ID 组,您可以很容易地构建您刚刚概述的数据框:

data = data.frame("ID"=c(1,1,1,2,3,3),
                  "S1"=c(NA,5,1,2,4,2),
                  "S2"=c(1,2,3,7,NA,11),
                  "T"=c(3,3,3,5,2,2))

newdata = data.frame("ID"=unique(data$ID),
                "S1.count"=aggregate(c(data$S1<=data$T)~data$ID,FUN=sum)[,2],
                "S2.count"=aggregate(c(data$S2<=data$T)~data$ID,FUN=sum)[,2],
                "S1.overall"=aggregate(c(!is.na(data$S1))~data$ID,FUN=sum)[,2],
                "S2.overall"=aggregate(c(!is.na(data$S2))~data$ID,FUN=sum)[,2])

newdata$S1.per = newdata$S1.count/newdata$S1.overall
newdata$S2.per = newdata$S2.count/newdata$S2.overall

我在这里使用逻辑向量来计算有效值和小于 T 值的数量。一个逻辑向量的和就是TRUE元素的个数。

这个短程序的输出是:

> newdata
  ID S1.count S2.count S1.overall S2.overall S1.per S2.per
1  1        1        3          2          3    0.5      1
2  2        1        0          1          1    1.0      0
3  3        1        0          2          1    0.5      0

【讨论】:

    【解决方案2】:

    使用dplyr,您可以计算如下:

    library(dplyr)
    
    df %>%
      group_by(ID) %>%
      summarise(across(starts_with('S'), list(count = ~sum(. <= T, na.rm = TRUE), 
                                              overall = ~sum(!is.na(.)), 
                                              per = ~mean(. <= T, na.rm = TRUE)))) %>%
      select(ID, ends_with('count'), ends_with('overall'), everything())
    
    #     ID S1_count S2_count S1_overall S2_overall S1_per S2_per
    #  <int>    <int>    <int>      <int>      <int>  <dbl>  <dbl>
    #1     1        1        3          2          3    0.5      1
    #2     2        1        0          1          1    1        0
    #3     3        1        0          2          1    0.5      0
    

    数据

    df <- structure(list(ID = c(1L, 1L, 1L, 2L, 3L, 3L), S1 = c(NA, 5L, 
    1L, 2L, 4L, 2L), S2 = c(1L, 2L, 3L, 7L, NA, 11L), T = c(3L, 3L, 
    3L, 5L, 2L, 2L)), class = "data.frame", row.names = c(NA, -6L))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 2015-05-16
      • 2016-01-29
      • 1970-01-01
      相关资源
      最近更新 更多