plyr计数排除未观察到的值

时间:2017-06-01 16:55:24

标签: r

我有一个被分类为案例(df$case==1)和非案例(df$case==0)的人的数据框,以及他们对可能取0到3的值的3个项目的回复。

对于每个项目,我想计算具有值2或3的案例的比例以及具有值2或3的非案例的比例。然后我想计算案例之间的比例差异和每个项目的非案例。

例如,在提供的玩具数据集中,有8个案例和8个非案例。对于item1,8个非案例中的2个具有2或3的值(比例为0.25)。在同一项目中,8个案例中有6个的值为2或3(比例为0.75。比例(或梯度)的差异当然是0.50。

item2的梯度为0,因为两组的比例均为0.50。

item3有问题。观察到的值不包括0,1或3,plyr::count(df, c("case", v))从表fr中排除这些值。因此,我非常丑陋的循环正在寻找fr中不存在的零计数。

我很乐观有一个3行整数解决方案可以结束这种疯狂;)

# setup
  df <- data.frame(case=c(0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1),
                   item1=c(0,1,2,3,0,1,2,3,0,0,0,0,3,3,3,3),
                   item2=c(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3),
                   item3=c(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2))

  vars <- c("item1", "item2", "item3")
  itemGradient <- as.data.frame(vars)
  gradient <- as.data.frame(NULL)

# calculate response frequencies by case-ness
  gr <- 1
  for (v in vars) {
    fr <- plyr::count(df, c("case", v))
    gradient[gr, 1] <- v                # item
    gradient[gr, 2] <- 0                # case
    gradient[gr, 3] <- fr[1, 3]         # option 0
    gradient[gr, 4] <- fr[2, 3]         # option 1
    gradient[gr, 5] <- fr[3, 3]         # option 2
    gradient[gr, 6] <- fr[4, 3]         # option 3
    gradient[gr+1, 1] <- v              # item
    gradient[gr+1, 2] <- 1              # case
    gradient[gr+1, 3] <- fr[5, 3]       # option 0
    gradient[gr+1, 4] <- fr[6, 3]       # option 1
    gradient[gr+1, 5] <- fr[7, 3]       # option 2
    gradient[gr+1, 6] <- fr[8, 3]       # option 3
    gr <- gr+2
  }
  names(gradient) <- c("item", "case", "r0", "r1", "r2", "r3")

# calculate proportion with values 2 or 3 by case
  gradient[is.na(gradient)] <- 0
  gradient$n <- rowSums(gradient[, c("r0", "r1", "r2", "r3")])
  gradient$r2or3 <- rowSums(gradient[, c("r2", "r3")])
  gradient$prop.r2or3 <- gradient$r2or3/gradient$n
  gradient

# calculate gradient score
  grad <- diff(gradient$prop.r2or3)
  grad <- grad[seq(1, length(grad), 2)]
  itemGradient <- data.frame(cbind(itemGradient, grad))
  names(itemGradient) <- c("item", "gradient")

2 个答案:

答案 0 :(得分:1)

我认为这样做。

library(dplyr)
library(tidyr)

df <- data_frame(case=c(0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1),
                 item1=c(0,1,2,3,0,1,2,3,0,0,0,0,3,3,3,3),
                 item2=c(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3),
                 item3=c(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2))

df %>% 
  group_by(case) %>% 
  summarise_all(funs(sum(. %in% 2:3)/n())) %>% 
  gather("item", "value", -case) %>% 
  spread(case, value) %>% 
  mutate(diff = `1` - `0`)

#> # A tibble: 3 x 4
#>    item   `0`   `1`  diff
#>   <chr> <dbl> <dbl> <dbl>
#> 1 item1  0.25  0.75   0.5
#> 2 item2  0.50  0.50   0.0
#> 3 item3  1.00  1.00   0.0

答案 1 :(得分:0)

您可以使用dplyr执行此操作:

df2 = df %>% 
group_by(case) %>%
summarise(prop1=sum(item1 %in% c(2,3)/n()),
prop2=sum(item2 %in% c(2,3)/n()),
prop3=sum(item3 %in% c(2,3)/n()))

返回:

   case prop1 prop2 prop3
  <dbl> <dbl> <dbl> <dbl>
1     0  0.25   0.5     1
2     1  0.75   0.5     1

然后你可以采取差异:

grad = df2[2,2:4]-df2[1,2:4]

  prop1 prop2 prop3
   0.5     0     0