【问题标题】:Two levels of longitudinal data: how to reshape?纵向数据的两个层次:如何重塑?
【发布时间】:2017-01-17 20:17:19
【问题描述】:

我有一个数据集,其中包含每个受试者的多个海马体积时间点。每个海马体积都有左右测量值。我现在想纵向比较左右变化。我知道如何为时间点重塑我的数据,但我不知道如何添加“边”的级别。

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

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

我应该应用 reshape 两次来获得左右的水平吗?还是有其他方法可以做到这一点?谢谢!

**我想要得到的是以下内容:

【问题讨论】:

  • 你能发布一个你希望你的输出数据是什么样子的例子吗?
  • 所以我只是添加了一个例子,谢谢

标签: r dataframe reshape2 multi-level


【解决方案1】:

一种方法是使用来自tidyrunitegatherseparate 的组合:

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. 每次T1T2T3的左列和右列首先unite,并将这些列命名为times1times2times3
  2. 然后,gather这三列命名键列times和值列Hipp
  3. separateHipp 列转换为LeftRight
  4. gather LeftRight 列命名键列 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)

这里,gather 中的键列 Side 具有原始 mydata 列名称的值。我们使用deployer::mutate 创建此列的副本,名为times。然后我们使用带有一些正则表达式的sub 来提取times 值的最后一位数字,并为Side 值提取LeftRight

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

【讨论】:

  • 您的mydata 中的level 是哪一列?
  • 谢谢!这正是重塑会给我的,但我还想为侧面(左/右)添加一个级别,而不仅仅是时间。所以我实际上有一个嵌套设计。我怎么得到它?
  • @user6121484:尝试编辑。结果并非完全按照您想要的方式排序,但长格式是您想要的。
  • @user6121484:我的第二个版本可能更接近你想要的。
  • @user6121484:只是为了让您知道,如果您对只有一次调用 gather 的第三个版本感兴趣,我已经更新了答案。
猜你喜欢
  • 1970-01-01
  • 2018-11-07
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
相关资源
最近更新 更多