Два уровня лонгитюдных данных: как изменить форму?

У меня есть набор данных с несколькими временными точками объема гиппокампа для каждого субъекта. Каждый объем гиппокампа имеет левое и правое измерение. Теперь я хочу сравнить левое и правое изменение в продольном направлении. Я знаю, как изменить свои данные для временных точек, но я не знаю, как добавить к ним уровни «стороны».

Итак, вот мой воспроизводимый набор данных:

mydata <- data.frame(SID=sample(1:150,400, replace=TRUE), hippLeft_T1=sample(6000:8000,400,replace=TRUE), hippRight_T1=sample(6000:8000,400,replace=TRUE),hippLeft_T2=sample(6000:8000,400,replace=TRUE), hippRight_T2=sample(6000:8000,400,replace=TRUE),hippLeft_T3=sample(6000:8000,400,replace=TRUE), hippRight_T3=sample(6000:8000,400,replace=TRUE))

Вот как я бы изменил его в продольном направлении:

long <- reshape(mydata, direction="long", varying=list(c(2,4,6),c(3,5,7)),idvar="SID", timevar="time", v.names=c("HippLeft","HippRight"), times=c("time1","time2","time3"))

Должен ли я применить изменение формы дважды, чтобы получить уровни для левого и правого? Или есть другой способ сделать это? Спасибо!

** Я пытаюсь получить следующее: введите здесь описание изображения


person user6121484    schedule 17.01.2017    source источник
comment
Можете ли вы опубликовать пример того, как вы надеетесь, что ваши выходные данные будут выглядеть?   -  person Cyrus Mohammadian    schedule 18.01.2017
comment
Так что я просто добавил пример, спасибо   -  person user6121484    schedule 18.01.2017


Ответы (1)


Один из способов сделать это — использовать комбинацию unite, gather и separate из tidyr:

library(tidyr)
long <- mydata %>% unite("times1", hippLeft_T1,hippRight_T1) %>%
                   unite("times2", hippLeft_T2,hippRight_T2) %>%
                   unite("times3", hippLeft_T3,hippRight_T3) %>%
                   gather("times","Hipp",times1:times3) %>%
                   separate(Hipp,c("Left","Right")) %>%
                   gather("Side","Hipp",Left:Right)

Заметки:

  1. Сначала unite левый и правый столбцы для каждого времени T1, T2 и T3 и назовите эти столбцы times1, times2 и times3.
  2. Затем gather эти три столбца, назвав ключевой столбец times и столбец значений Hipp.
  3. separate столбец Hipp на Left и Right
  4. gather столбцы Left и Right, именующие ключевой столбец Side и столбец значений Hipp

На самом деле лучший способ — поменять местами две операции gather, сначала объединив время:

library(tidyr)
long <- mydata %>% unite("Left", hippLeft_T1,hippLeft_T2,hippLeft_T3) %>%
                   unite("Right", hippRight_T1,hippRight_T2,hippRight_T3) %>%
                   gather("Side","Hipp",Left:Right) %>%
                   separate(Hipp,c("times1","times2","times3")) %>%
                   gather("times","Hipp",times1:times3)

Третий подход, использующий только один вызов gather:

library(dplyr)
library(tidyr)
long <- mydata %>% gather("Side","Hipp",-SID) %>%
                   mutate(times=paste0("times",sub(".*(\\d)$","\\1",Side)),
                          Side=sub("^hipp([A-z]+)_T.*","\\1",Side)) %>%
                   select(SID,Side,times,Hipp)

Здесь ключевой столбец Side из gather имеет значения, которые являются исходными именами столбцов mydata. Мы используем deployer::mutate для создания дубликата этого столбца с именем times. Затем мы используем sub с некоторым регулярным выражением, чтобы извлечь последнюю цифру для значений times и извлечь либо Left, либо Right для значений Side.

Установив начальное значение 123, ваши данные:

set.seed(123)
mydata <- data.frame(SID=sample(1:150,400, replace=TRUE), hippLeft_T1=sample(6000:8000,400,replace=TRUE), hippRight_T1=sample(6000:8000,400,replace=TRUE),hippLeft_T2=sample(6000:8000,400,replace=TRUE), hippRight_T2=sample(6000:8000,400,replace=TRUE),hippLeft_T3=sample(6000:8000,400,replace=TRUE), hippRight_T3=sample(6000:8000,400,replace=TRUE))
head(mydata)
##  SID hippLeft_T1 hippRight_T1 hippLeft_T2 hippRight_T2 hippLeft_T3 hippRight_T3
##1  44        7973         6941        7718         7279        6319         7465
##2 119        6274         6732        7775         6249        6289         7220
##3  62        7811         6242        6978         6510        6298         6448
##4 133        7153         6094        7436         7641        7029         7833
##5 142        6791         6525        6973         7608        6986         7606
##6   7        6900         7938        7978         6091        7233         6625

Результат использования второго или третьего подхода:

print(long)
##     SID  Side  times Hipp
##   1  44  Left times1 7973
##   2 119  Left times1 6274
##   3  62  Left times1 7811
##   4 133  Left times1 7153
##   5 142  Left times1 6791
##   6   7  Left times1 6900
## ...
## 401  44 Right times1 6941
## 402 119 Right times1 6732
## 403  62 Right times1 6242
## 404 133 Right times1 6094
## 405 142 Right times1 6525
## 406   7 Right times1 7938
## ...
## 801  44  Left times2 7718
## 802 119  Left times2 7775
## 803  62  Left times2 6978
## 804 133  Left times2 7436
## 805 142  Left times2 6973
## 806   7  Left times2 7978
## ...
##1201  44 Right times2 7279
##1202 119 Right times2 6249
##1203  62 Right times2 6510
##1204 133 Right times2 7641
##1205 142 Right times2 7608
##1206   7 Right times2 6091
## ...
##1601  44  Left times3 6319
##1602 119  Left times3 6289
##1603  62  Left times3 6298
##1604 133  Left times3 7029
##1605 142  Left times3 6986
##1606   7  Left times3 7233
## ...
##2001  44 Right times3 7465
##2002 119 Right times3 7220
##2003  62 Right times3 6448
##2004 133 Right times3 7833
##2005 142 Right times3 7606
##2006   7 Right times3 6625
person aichao    schedule 17.01.2017
comment
Какой столбец level в вашем mydata? - person aichao; 18.01.2017
comment
Спасибо! Это именно то, что дало бы мне изменение формы, но я также хочу добавить уровень для стороны (левой/правой), а не только времени. Так что у меня на самом деле есть вложенный дизайн. Как мне это получить? - person user6121484; 18.01.2017
comment
@ user6121484: попробуйте отредактировать. Результат не упорядочен именно так, как вы хотите, но длинный формат — это то, что вам нужно. - person aichao; 18.01.2017
comment
@ user6121484: моя вторая версия может быть ближе к тому, что вы хотите. - person aichao; 18.01.2017
comment
@ user6121484: Просто чтобы вы знали, что если вас интересует третья версия, в которой есть только один вызов gather, я обновил ответ. - person aichao; 18.01.2017