【问题标题】:Count and filter data based on paired data/every two rows?根据配对数据/每两行计算和过滤数据?
【发布时间】:2021-03-07 22:51:22
【问题描述】:

尝试设置 McNemar 测试,但我不能很好地编码(使用 R)

我的数据是配对的,它有 1000 对长,所以我有一列指定配对编号,例如

 c(0 , 0 , 1, 1, 2, 2, 3, 3, 4, 4)

一列指定该对中的哪个成员在对照组或治疗组中(每对有一个玩家,但顺序随机),例如:

c(0, 1, 1, 0, 1, 0, 0, 1, 0, 1)

还有一个名为 response 的列,其中任何一个、一个或两个成员都不会收到如下响应:

c(0, 1, 1, 1, 1, 0, 0, 0, 0, 1)

我正在尝试创建一个矩阵来计算结果,例如:

a <- count of pairs in which both members received a response
b <- count of pairs in which the control only received a response
c <- treatment only response
d <- Neither response
matrix(c(a, b, c, d), 2, 2)

我可以运行哪些代码行来过滤我的数据以获取 a、b、c 和 d? 我一直在尝试使用 tidyverse 包,所以它可能是 base R 或 tidyverse

【问题讨论】:

    标签: r dataframe data-cleaning data-wrangling


    【解决方案1】:

    tidyverse/dplyr 的这种方法有效:

    1.加载您的数据

    library(tidyverse)
    
    pair <- c(0 , 0 , 1, 1, 2, 2, 3, 3, 4, 4)
    treat <- c(0, 1, 1, 0, 1, 0, 0, 1, 0, 1)
    response <- c(0, 1, 1, 1, 1, 0, 0, 0, 0, 1)
    data <- data.frame(pair, treat, response)
    

    2。计算你想要的计数:

    d <- data %>% group_by(pair) %>%
        mutate(total_response = sum(response)) %>%
        ungroup() %>% mutate(a = case_when(
            total_response==2 ~ 1,
            TRUE ~ 0),
            b = case_when(
                total_response==1 & treat==0 & response == 1 ~ 1,
            TRUE ~ 0),
            c = case_when(
                total_response==1 & treat==1 & response == 1  ~ 1,
            TRUE ~ 0), 
            d = case_when(
                total_response == 0 ~ 1,
            TRUE ~ 0)) %>% group_by(pair) %>%
        summarise(a = max(a),
                  b = max(b),
                  c = max(c),
                  d = max(d)) %>%
        ungroup() %>%
        summarise(a = sum(a),
                  b = sum(b),
                  c = sum(c),
                  d = sum(d))
    

    3.你的矩阵:

    matrix(c(d$a, d$b, d$c, d$d), 2, 2)
    

    4.解释计算:

    1. 首先,您将成对分组的响应相加;
    2. 然后,您取消组合,当有两个成对响应时,a=1;当一个响应和一个控制响应时,b=1;当一个响应和治疗响应时,c=1;无响应时,d=1;
    3. 然后,你再次成对分组,得到每个字母值的最大值,所以你只能成对得到一个字母值;
    4. 最后,您取消分组并对每个变量的值求和(相当于计算每个变量的值);

    【讨论】:

    • 该矩阵的计数比总对 (5) 多三个计数。 'b' 的计数应该为零。
    • @LC-datascientist ,感谢您的指出。我编辑并纠正了这个问题。 case_when 子句中缺少一个条件。
    【解决方案2】:

    假设您的数据框如下所示

    > d
       group treatment response
    1      0         0        0
    2      0         1        1
    3      1         1        1
    4      1         0        1
    5      2         1        1
    6      2         0        0
    7      3         0        0
    8      3         1        0
    9      4         0        0
    10     4         1        1
    

    那你可以试试这样的

    d <- within(d, {
      response <- factor(response, levels = c(1, 0), labels = c("positive", "negative"))
      treatment <- as.logical(treatment)
    })
    
    with(d, table(response[!treatment], response[treatment], dnn = c("control", "treatment")))
    

    输出

              treatment
    control    positive negative
      positive        1        0
      negative        3        1
    

    【讨论】:

      【解决方案3】:

      这是使用dplyr R 包的方法:

      library(dplyr)
      
      # your data
      df <- data.frame(
          pair = c(0 , 0 , 1, 1, 2, 2, 3, 3, 4, 4), 
          treatment = c(0, 1, 1, 0, 1, 0, 0, 1, 0, 1), 
          response = c(0, 1, 1, 1, 1, 0, 0, 0, 0, 1))
      
      # data management
      df2 <- df %>% 
          group_by(pair) %>% 
          arrange(treatment) %>% 
          summarise_all(funs(toString(na.omit(.))))
      df2
      ## A tibble: 5 x 3
      #   pair treatment response
      #  <dbl> <chr>     <chr>   
      #1     0 0, 1      0, 1    
      #2     1 0, 1      1, 1    
      #3     2 0, 1      0, 1    
      #4     3 0, 1      0, 0    
      #5     4 0, 1      0, 1 
      
      # contingency table
      df2 %>% summarise(
          a = sum(response == '1, 1'), # count of pairs in which both members received a response
          b = sum(response == '1, 0'), # count of pairs in which the control only received a response
          c = sum(response == '0, 1'), # count of pairs in which the treatment only received a response
          d = sum(response == '0, 0')  # count of pairs in which neither members received a response
      ) %>% matrix(2,2)
      #     [,1] [,2]
      #[1,] 1    3   
      #[2,] 0    1   
      

      说明:数据管理

      这里的目标是使用summarise_all(funs(toString(na.omit(.)))) 折叠成对行中的响应值。这将允许您确定数据中有多少成对的 c(1, 1)、c(1, 0)、c(0, 1) 和 c(0, 0) 响应。

      group_by(pair) 使所有进一步的操作在pair 组内完成。
      arrange(treatment) 根据treatment 列(在每个pair 组内)对行重新排序,以便控制响应和处理的顺序每一对的响应总是以相同的顺序排列——即,成对的响应总是首先是控制,其次是治疗。
      summarise_all(funs(toString(na.omit(.)))) 将所有非 NA 元素(每个 pair 组内)连接到一行。

      特别是因为group_by(pair)summarise_all(...)df2 对于每个pair 标识符都有一行。

      说明:列联表

      summarise(...) 内,每个 TRUE 响应条件的计数都分配给它们各自的向量。列联表(矩阵)是根据计数创建的,与所讨论的matrix(c(a, b, c, d), 2, 2) 的组织方式相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-04
        • 1970-01-01
        • 2014-03-04
        • 1970-01-01
        • 1970-01-01
        • 2019-04-27
        相关资源
        最近更新 更多