Вычислить различия между строками в кадре данных в зависимости от значений в столбце - PullRequest
0 голосов
/ 07 февраля 2019

Допустим, у меня есть следующая структура данных:

structure(list(treatment = c("DD", "DR", "RD", "RR", "DD", "DR", 
"RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", 
"DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", 
"DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", 
"RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", 
"RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", 
"DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", 
"DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", 
"RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", 
"RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", 
"DR", "RD", "RR", "DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR", 
"DD", "DR", "RD", "RR", "DD", "DR", "RD", "RR"), correct = c(0.428571428571429, 
0.6, 0.625, 0.75, 0.757142857142857, 0.725, 0.675, 0.65, 0.971428571428571, 
0.875, 0.875, 0.875, 0.442857142857143, 0.35, 0.325, 0.425, 0.942857142857143, 
0.975, 0.925, 0.9, 0.171428571428571, 0.15, 0.175, 0.2375, 0.714285714285714, 
0.925, 0.95, 0.825, 0.957142857142857, 0.925, 0.9, 0.9125, 0.228571428571429, 
0.275, 0.275, 0.4625, 0.9, 0.8, 0.825, 0.725, 0.971428571428571, 
0.9, 0.85, 0.9375, 0.885714285714286, 0.925, 0.925, 0.95, 0.857142857142857, 
0.85, 0.85, 0.825, 0.857142857142857, 0.75, 0.75, 0.925, 0.942857142857143, 
0.925, 0.925, 0.825, 0.871428571428571, 0.8, 0.8, 0.6375, 0.957142857142857, 
0.925, 0.925, 0.85, 1, 0.925, 0.9, 0.975, 0.971428571428571, 
0.925, 0.9, 0.9375, 0.9, 0.925, 0.95, 1, 0.971428571428571, 0.95, 
0.95, 1, 0.914285714285714, 0.95, 0.95, 0.95, 0.614285714285714, 
0.775, 0.8, 0.575, 0.428571428571429, 0.575, 0.575, 0.45, 0.2, 
0.375, 0.375, 0.4625, 0.971428571428571, 0.975, 0.975, 0.975, 
0.9, 0.8, 0.8, 0.8625, 0.885714285714286, 0.9, 0.85, 0.8125, 
0.2, 0.275, 0.3, 0.2875, 0.671428571428571, 0.775, 0.8, 0.875, 
0.971428571428571, 0.95, 0.95, 1)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -124L))

Каждые четыре строки представляют значения для данного вопроса (для разных групп).Я хочу иметь возможность вычислять (DD - DR) и (RR - RD) для каждого набора из четырех строк и хранить каждый из них в двух отдельных столбцах.

Мне известна команда «diff», которая косвенно получит мне то, что, если я подгруппирую данные для включения только DD и DR, а другую - только для RD и RR, но я надеялся на более явнуюметод.

Результирующая таблица будет иметь четыре столбца (Treatment, Correct, DD-DR и RR-RD), а последние два столбца будут по существу представлять группировку по «вопросу» (каждые четыре строки) и явно приниматьразница между DD и DR и RR и RD.

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Предполагая, что строки всегда сгруппированы по соседству, и это всегда 4 для каждой группы, это то, что вы ищете?

library (tidyverse)

dat %>%
  group_by(id = 1 + (row_number()-1) %/% 4) %>%
  mutate(dd_less_dr = 
           sum(if_else(treatment == "DD", correct, 0)) - 
           sum(if_else(treatment == "DR", correct, 0)),
         rr_less_rd =
           sum(if_else(treatment == "RR", correct, 0)) - 
           sum(if_else(treatment == "RD", correct, 0)))

# A tibble: 124 x 5
# Groups:   id [31]
   treatment correct    id dd_less_dr rr_less_rd
   <chr>       <dbl> <dbl>      <dbl>      <dbl>
 1 DD          0.429     1    -0.171       0.125
 2 DR          0.6       1    -0.171       0.125
 3 RD          0.625     1    -0.171       0.125
 4 RR          0.75      1    -0.171       0.125
 5 DD          0.757     2     0.0321     -0.025
 6 DR          0.725     2     0.0321     -0.025
 7 RD          0.675     2     0.0321     -0.025
 8 RR          0.65      2     0.0321     -0.025
...
0 голосов
/ 07 февраля 2019

Как насчет

dat %>%
  mutate(group = ceiling(row_number()/4)) %>%
  spread(key = treatment, value = correct) %>%
  mutate(`DD-DR` = DD - DR,
         `RR - RD` = RR - RD)

# A tibble: 31 x 7
   group    DD    DR    RD    RR `DD-DR` `RR - RD`
   <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>     <dbl>
 1     1 0.429 0.6   0.625 0.75  -0.171     0.125 
 2     2 0.757 0.725 0.675 0.65   0.0321   -0.025 
 3     3 0.971 0.875 0.875 0.875  0.0964    0     
 4     4 0.443 0.35  0.325 0.425  0.0929    0.100 

благодаря lukeA для кода потолка / номера.

0 голосов
/ 07 февраля 2019

Вы можете создать id для идентификации каждого вопроса.Таким образом, вы можете использовать spread просто для простоты.После этого вы можете рассчитать DD-DR и RR-RD.Просто чтобы вернуться к исходному формату, вы можете использовать gather, но это не обязательно.

library(dplyr)
library(tidyr)

df$id <- rep(1:(nrow(df)/4), each = 4)
df %>%
  spread(key = treatment, value = correct) %>%
  mutate(DD_DR = DD-DR,
         RR_RD = RR-RD) %>%
  gather(key = treatment, value = correct, -id, -DD_DR, -RR_RD) %>%
  select(id, treatment, correct, DD_DR, RR_RD) %>%
  arrange(id) %>%
  head(10)

# A tibble: 10 x 5
      id treatment correct   DD_DR  RR_RD
   <int> <chr>       <dbl>   <dbl>  <dbl>
 1     1 DD          0.429 -0.171   0.125
 2     1 DR          0.6   -0.171   0.125
 3     1 RD          0.625 -0.171   0.125
 4     1 RR          0.75  -0.171   0.125
 5     2 DD          0.757  0.0321 -0.025
 6     2 DR          0.725  0.0321 -0.025
 7     2 RD          0.675  0.0321 -0.025
 8     2 RR          0.65   0.0321 -0.025
 9     3 DD          0.971  0.0964  0    
10     3 DR          0.875  0.0964  0   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...