对于具有 'quadruple nesting' 的多级结构,如何将宽数据帧转换为长数据帧?
How do I convert a wide dataframe to a long dataframe for a multilevel structure with 'quadruple nesting'?
我进行了一项研究,回想起来(一个人生活,一个人学习 :-))似乎生成了多层次数据。现在我正在尝试将数据集从宽到长重组,以便我可以使用例如分析它lme4.
在这样做的过程中,我遇到了一个,嗯,挑战,我以前 运行 遇到过几次,但我从未找到好的解决方案。这次我又搜索了一下,但我可能使用了错误的关键字 - 或者这个问题比我想象的要少得多。
基本上,在这个数据集中,变量名指示收集的测量数据。我要求参与者对干预措施进行评分(评分)(真的可以是任何东西)。每种干预都属于 6 个行为领域之一。此外,参与者对每项干预措施进行评分,无论是在它单独出现时,还是与其他干预措施同时出现时,或与其他两种干预措施同时出现时。共有三种类型的干预措施,它们都在我向他们提供了一些信息之前(t0)和之后(t1)进行了评分。
所以,实际上,我有一个可以像这样重新生成的数据框:
### Elements of the variable names
measurementMomentsVector <- c("t0", "t1");
interventionTypesVector <- c("fear", "know", "scd");
nrOfInterventionsSimultaneouslyVector <- c(1, 2, 3);
behaviorDomainsVector <- c("diet", "pox", "alc", "smoking", "traff", "adh");
### Generate a vector with all variable names
variableNames <-
apply(expand.grid(measurementMomentsVector,
interventionTypesVector,
nrOfInterventionsSimultaneouslyVector,
behaviorDomainsVector),
1, paste0, collapse="_");
### Generate 5 'participants' worth of data
wideData <- data.frame(matrix(rnorm(5*length(variableNames)), nrow=5));
### Assign names
names(wideData) <- variableNames;
### Add unique id variable for every participants
wideData$id <- 1:5;
所以使用head(wideData)[, 1:5]
你可以大致看到数据框的样子:
t0_fear_1_diet t1_fear_1_diet t0_know_1_diet t1_know_1_diet t0_scd_1_diet
1 -0.9338191 0.9747453 1.0069036 0.3500103 -0.844699708
2 0.8921867 1.3687834 -1.2005791 0.2747955 1.316768219
3 1.6200200 0.5245470 -1.2910586 1.3211912 -0.174795144
4 0.1543738 0.7535642 0.4726131 -0.3464789 -0.009190702
5 -1.3676692 -0.4491574 -2.0902003 -0.3484678 -2.537501824
现在,我想将此数据转换为一个长数据帧,有 6 个变量,例如 'id'、'measurementMoment'、'interventionType'、'nrOfInterventionsSimultaneously'、'behaviorDomain'和'evaluation',其中第一个变量表示记录所属的参与者,最后一个变量是参与者给出特定干预的分数(等级、等级、评价),中间的四个变量指明正在对哪种干预进行准确评级。
我可能会为这个问题写一些 'custom' 代码,但我希望 R 'has something for this'。我一直在玩 reshape2,例如:
longData <- reshape(wideData, varying=1:(ncol(wideData)-1),
idvar="id",
sep="_", direction="long")
但它无法猜测时变变量:
Error in guess(varying) :
failed to guess time-varying variables from their names
我已经为这个问题纠结过好几次了,但我没能在网上找到任何答案。现在我真的需要继续前进,所以我想我会在写一些定制的东西之前尝试这个作为最后的努力:-)
如果有人能提供任何指点,我将不胜感激!!!
我认为您的问题可以通过两步法解决:
- 将您的数据融合到一个长
data.frame
中(或者像我一样,在一个长 data.table
中)
- 将包含所有标签的
variable
列拆分为每个所需分组变量的单独列。
由于相关信息在标签中,因此可以使用 data.table
包中的 tstrsplit
函数轻松实现。
您可能正在寻找以下内容:
library(data.table)
longData <- melt(setDT(wideData), id.vars="id")
longData[, c("moment", "intervention", "number", "behavior") :=
tstrsplit(variable, "_", type.convert = TRUE)
][, variable:=NULL]
结果:
> head(longData,15)
id value moment intervention number behavior
1: 1 -0.07747254 t0 fear 1 diet
2: 2 -0.76207379 t0 fear 1 diet
3: 3 1.15501244 t0 fear 1 diet
4: 4 1.24792369 t0 fear 1 diet
5: 5 -0.28226121 t0 fear 1 diet
6: 1 -1.04875354 t1 fear 1 diet
7: 2 -0.91436882 t1 fear 1 diet
8: 3 0.72863487 t1 fear 1 diet
9: 4 0.10934261 t1 fear 1 diet
10: 5 -0.06093002 t1 fear 1 diet
11: 1 -0.70725760 t0 know 1 diet
12: 2 1.06309003 t0 know 1 diet
13: 3 0.89501164 t0 know 1 diet
14: 4 1.48148316 t0 know 1 diet
15: 5 0.22086835 t0 know 1 diet
作为 data.table
的替代方法,您还可以使用 splitstackshape
包的 cSplit
函数拆分 variable
列(您必须重命名结果之后可变列):
library(splitstackshape)
longData <- cSplit(longData, sep="_", "variable", "wide", type.convert=TRUE)
names(longData) <- c("id","value","moment","intervention","number","behavior")
或 tidyr
:
library(tidyr)
separate(longData, variable, c("moment", "intervention", "number", "behavior"), sep="_", remove=TRUE)
我进行了一项研究,回想起来(一个人生活,一个人学习 :-))似乎生成了多层次数据。现在我正在尝试将数据集从宽到长重组,以便我可以使用例如分析它lme4.
在这样做的过程中,我遇到了一个,嗯,挑战,我以前 运行 遇到过几次,但我从未找到好的解决方案。这次我又搜索了一下,但我可能使用了错误的关键字 - 或者这个问题比我想象的要少得多。
基本上,在这个数据集中,变量名指示收集的测量数据。我要求参与者对干预措施进行评分(评分)(真的可以是任何东西)。每种干预都属于 6 个行为领域之一。此外,参与者对每项干预措施进行评分,无论是在它单独出现时,还是与其他干预措施同时出现时,或与其他两种干预措施同时出现时。共有三种类型的干预措施,它们都在我向他们提供了一些信息之前(t0)和之后(t1)进行了评分。
所以,实际上,我有一个可以像这样重新生成的数据框:
### Elements of the variable names
measurementMomentsVector <- c("t0", "t1");
interventionTypesVector <- c("fear", "know", "scd");
nrOfInterventionsSimultaneouslyVector <- c(1, 2, 3);
behaviorDomainsVector <- c("diet", "pox", "alc", "smoking", "traff", "adh");
### Generate a vector with all variable names
variableNames <-
apply(expand.grid(measurementMomentsVector,
interventionTypesVector,
nrOfInterventionsSimultaneouslyVector,
behaviorDomainsVector),
1, paste0, collapse="_");
### Generate 5 'participants' worth of data
wideData <- data.frame(matrix(rnorm(5*length(variableNames)), nrow=5));
### Assign names
names(wideData) <- variableNames;
### Add unique id variable for every participants
wideData$id <- 1:5;
所以使用head(wideData)[, 1:5]
你可以大致看到数据框的样子:
t0_fear_1_diet t1_fear_1_diet t0_know_1_diet t1_know_1_diet t0_scd_1_diet
1 -0.9338191 0.9747453 1.0069036 0.3500103 -0.844699708
2 0.8921867 1.3687834 -1.2005791 0.2747955 1.316768219
3 1.6200200 0.5245470 -1.2910586 1.3211912 -0.174795144
4 0.1543738 0.7535642 0.4726131 -0.3464789 -0.009190702
5 -1.3676692 -0.4491574 -2.0902003 -0.3484678 -2.537501824
现在,我想将此数据转换为一个长数据帧,有 6 个变量,例如 'id'、'measurementMoment'、'interventionType'、'nrOfInterventionsSimultaneously'、'behaviorDomain'和'evaluation',其中第一个变量表示记录所属的参与者,最后一个变量是参与者给出特定干预的分数(等级、等级、评价),中间的四个变量指明正在对哪种干预进行准确评级。
我可能会为这个问题写一些 'custom' 代码,但我希望 R 'has something for this'。我一直在玩 reshape2,例如:
longData <- reshape(wideData, varying=1:(ncol(wideData)-1),
idvar="id",
sep="_", direction="long")
但它无法猜测时变变量:
Error in guess(varying) :
failed to guess time-varying variables from their names
我已经为这个问题纠结过好几次了,但我没能在网上找到任何答案。现在我真的需要继续前进,所以我想我会在写一些定制的东西之前尝试这个作为最后的努力:-)
如果有人能提供任何指点,我将不胜感激!!!
我认为您的问题可以通过两步法解决:
- 将您的数据融合到一个长
data.frame
中(或者像我一样,在一个长data.table
中) - 将包含所有标签的
variable
列拆分为每个所需分组变量的单独列。
由于相关信息在标签中,因此可以使用 data.table
包中的 tstrsplit
函数轻松实现。
您可能正在寻找以下内容:
library(data.table)
longData <- melt(setDT(wideData), id.vars="id")
longData[, c("moment", "intervention", "number", "behavior") :=
tstrsplit(variable, "_", type.convert = TRUE)
][, variable:=NULL]
结果:
> head(longData,15)
id value moment intervention number behavior
1: 1 -0.07747254 t0 fear 1 diet
2: 2 -0.76207379 t0 fear 1 diet
3: 3 1.15501244 t0 fear 1 diet
4: 4 1.24792369 t0 fear 1 diet
5: 5 -0.28226121 t0 fear 1 diet
6: 1 -1.04875354 t1 fear 1 diet
7: 2 -0.91436882 t1 fear 1 diet
8: 3 0.72863487 t1 fear 1 diet
9: 4 0.10934261 t1 fear 1 diet
10: 5 -0.06093002 t1 fear 1 diet
11: 1 -0.70725760 t0 know 1 diet
12: 2 1.06309003 t0 know 1 diet
13: 3 0.89501164 t0 know 1 diet
14: 4 1.48148316 t0 know 1 diet
15: 5 0.22086835 t0 know 1 diet
作为 data.table
的替代方法,您还可以使用 splitstackshape
包的 cSplit
函数拆分 variable
列(您必须重命名结果之后可变列):
library(splitstackshape)
longData <- cSplit(longData, sep="_", "variable", "wide", type.convert=TRUE)
names(longData) <- c("id","value","moment","intervention","number","behavior")
或 tidyr
:
library(tidyr)
separate(longData, variable, c("moment", "intervention", "number", "behavior"), sep="_", remove=TRUE)