Собрать дважды в одном кадре данных - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть фрейм данных, где я хочу сделать две отдельные сборки

library(tidyverse)
id <- c("A","B","C","D","E")
test_1_baseline <- c(1,2,4,5,6)
test_2_baseline <- c(21000, 23400, 26800,29000,30000)
test_1_followup <- c(0,4,2,3,1)
test_2_followup <- c(10000,12000,13000,15000,21000)
layout_1 <-data.frame(id,test_1_baseline,test_1_followup,test_2_baseline,test_2_followup)

Это текущая раскладка.У каждого человека есть 1 строка.Результат теста 1 на базовом уровне - одна переменная Результат теста 2 на базовом уровне - вторая переменная. То же самое относится и к последующим результатам теста 1/2

Я бы хотел, чтобы данные были более аккуратными.Один столбец для момента времени, один для результата теста A, один для результата теста B.

id2 <- c("A","B","C","D","E","A","B","C","D","E")
time <- c(rep("baseline",5),rep("followup",5))
test_1_result <- c(1,2,4,5,6,0,4,2,3,1)
test_2_result <- c(21000, 23400, 26800,29000,30000,10000,12000,13000,15000,21000)
layout_2 <- data.frame(id2, time,test_1_result,test_2_result)

В настоящее время я делаю то, что мне кажется странным, когда я в первую очередь собираю данные теста 1

test_1 <-  select(layout_1,id,test_1_baseline,test_1_followup) %>%
  gather("Timepoint","test_1",c(test_1_baseline,test_1_followup)) %>% 
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_1_baseline", "baseline")) %>%
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_1_followup", "followup"))

Затем я делаю то же самое для теста 2 и присоединяюсь к ним

test_2 <- select(layout_1,id,test_2_baseline,test_2_followup) %>%
  gather("Timepoint","test_2",c(test_2_baseline,test_2_followup)) %>% 
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_2_baseline", "baseline")) %>%
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_2_followup", "followup"))   

test_combined <- full_join(test_1,test_2)

Я попытался выполнить первый сбор, а затем второй на том же кадре данных, но затем вы получите дубликаты;т. е. вы получите

  1. ID 1 Test_1 Baseline Test_2 Baseline
  2. ID 1 Test_1 Baseline Test_2 Followup
  3. ID 1 Test_1 Контрольный тест_2
  4. BaselineID 1 Test_1 Followup Test_2 Followup == 4 строки, где должно быть только 2

Я чувствую, что для этого должен быть более понятный способ.Руководство приветствуется

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Вы можете gather все столбцы, кроме id, затем использовать separate для разделения на результат и время.

Обратите внимание, что в этом коде предполагается, что имя результата всегда состоит из 6 символов (test_1, test_2), и разделяется на основе этого предположения.Вам нужно будет разработать другой separate, если это не так.

library(tidyr)
library(dplyr)

layout_1 %>% 
  gather(Var, Val, -id) %>% 
  separate(Var, into = c("result", "time"), sep = 6) %>% 
  spread(result, Val) %>% 
  mutate(time = gsub("_", "", time))

Результат:

   id     time test_1 test_2
1   A baseline      1  21000
2   A followup      0  10000
3   B baseline      2  23400
4   B followup      4  12000
5   C baseline      4  26800
6   C followup      2  13000
7   D baseline      5  29000
8   D followup      3  15000
9   E baseline      6  30000
10  E followup      1  21000
0 голосов
/ 27 ноября 2018

Один вариант с data.table с использованием melt, который может принимать несколько measure patterns

library(data.table)
nm1 <- unique(sub(".*_", "", names(layout_1)[-1]))
melt(setDT(layout_1), measure = patterns("test_1", "test_2"),
          value.name = c('test_1_result', 'test_2_result'), 
          variable.name = 'time')[, time := nm1[time]][]
...