两级纵向数据:如何重塑?

时间:2017-01-17 20:17:19

标签: r dataframe reshape2 multi-level

我有一个数据集,每个受试者有多个海马体积时间点。每个海马体积具有左右测量。我现在想要纵向比较左右变化。我知道如何重塑我的数据的时间点,但我不知道如何添加“侧”的水平。

所以这是我可重复的数据集:

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"))

我应该重新应用重塑两次以获得左右的水平吗?或者还有另一种方法吗?谢谢!

**我想要得到的是以下内容: enter image description here

1 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是使用unitegatherseparatetidyr的组合:

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. 每次uniteT1T2的左右列首先T3,并将这些列命名为times1times2times3
  2. 然后,gather这三个列命名了关键列times和值列Hipp
  3. separateHipp列添加到LeftRight
  4. gather LeftRight列命名关键列Side和值列Hipp
  5. 实际上,更好的方法是首先将两个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值提取RightSide

    将种子设置为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