3

尝试设置 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

4

3 回答 3

3

这种方法与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. 最后,您将每个变量的值取消分组并求和(相当于计算每个变量的值);
于 2020-11-25T06:03:58.753 回答
1

假设您的数据框看起来像这样

> 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
于 2020-11-25T06:53:46.617 回答
1

这是使用dplyrR 包的方法:

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)and summarise_all(...),每个标识符df2都有一行。pair

说明:列联表

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

于 2020-11-25T07:15:46.213 回答