【问题标题】:Reshaping Wide to Long but not reshaping all variables on R [duplicate]将Wide重塑为Long但不重塑R上的所有变量[重复]
【发布时间】:2021-10-12 05:26:24
【问题描述】:

很抱歉打扰您。我有一个纵向数据集,但它是宽格式的。

有 380 个变量和 3000 多个 id。

我正在尝试将数据转换为长格式,以便有一个时间变量列。

时间变量由每个列变量前面的后缀表示,因此 V0 是基线时间,并且 V01 是 1 年的时间。 V02 是第二年的时间。 V03 是 3 年等的时间。

大部分变量都使用这个时间变量进行分类,但不是全部。 所以 v0pase 是基线的 pase。 V01pase是1年的pase。

并非所有变量都有时间变量。有些是分类的,例如性别、抑郁等。

我正在尝试在 R 中将其重塑为长格式,但是我的代码似乎不起作用:

数据库名为“TrialData”

TrialDataLong <- reshape(TrialData, varying = c((grepl("v",))), direction = "long", 
                                              timevar = "visit/year", idvar = 
                                             "id", sep = "v")

我已将旧数据快照的图像与我的目标相关联。

如果有人可以提供帮助,我将不胜感激。我对 R 很陌生。

非常感谢。

最好的祝愿 詹姆斯

【问题讨论】:

标签: r tidyverse transform reshape


【解决方案1】:

这是您可以使用的另一种解决方案。以下是有关解决方案的一些说明:

  • 除变量IDsex 外,原始数据集的其他变量具有不同的名称模式。它以一个非数字字符开头,后跟一个数字,然后是一对非数字字符
  • 根据第二个数据集的名称,我们只对捕获名称的数字部分和后面的一对非数字感兴趣,丢弃开始的非数字字符
  • 所以我必须定义 2 个捕获组,第一个是正则表达式中由 (\\d) 表示的一个数字,第二个是由 ([a-z]{3,}) 表示的至少 3 个非数字。您可能会注意{3,},我将另一端打开,例如{3,4} 表示在 3 到 4 个字符之间
  • 在此正则表达式“az([az]{3,})”中,第一部分 [a-z] 表示与第一个数据集的起始名称相对应的任何非数字字符,但您注意到它没有放在括号,因为我们不需要捕获它们
  • 至于names_to 参数,还定义了2 个组,对应于names_pattern 中的两个捕获组,第一个组将放入Time 变量中,这里是更有趣的.value 值,它表示部分名称(第二组)实际上是我们要测量的值,它们是 pasedep

还有其他方法可以实现这一点,这是一种方法。

library(dplyr)
library(tidyr)

TrialDataLong %>%
  pivot_longer(starts_with("v"), 
               names_to = c("Time", ".value"), 
               names_pattern = "[a-z](\\d)([A-Za-z]{3,})")

# A tibble: 8 x 5
     id sex   Time   pase dep  
  <dbl> <chr> <chr> <dbl> <chr>
1     1 M     0        10 Yes  
2     1 M     1        12 Yes  
3     1 M     2        14 Yes  
4     1 M     3        13 Yes  
5     2 F     0        15 No   
6     2 F     1        15 Yes  
7     2 F     2        16 Yes  
8     2 F     3        16 Yes  

【讨论】:

  • 这非常好用。非常感谢。我想知道您能否解释一下您在“names_pattern”="[a-z](\\d)([a-z]{3,})" 中使用的符号背后的含义。每个部分是什么意思?我试着用谷歌搜索每一点,但这非常具有挑战性。大概 (!c(id, sex) 部分中的所有列变量都意味着“旋转时间更长,除了将这些变量附加到每个 ID”。因此,我可以在这部分添加更多变量,我想保持不变?
  • 不客气,我添加了一些注释,如果您有任何问题,请告诉我。顺便说一句,通过使用!c(id, sex),我排除了这两列并使用了其余列。
  • ID mostid性别年龄种族v0bmi v0smoke v0Comorbidity_Score v0Depression v0wototr v0wototl v0menr v0menl v0pase v0KLGLeft v1KLGLeft v2KLGLeft v3KLGLeft v5KLGLeft v0KLGRight v1KLGRight v2KLGRight v3KLGRight v5KLGRight v1bmi v2bmi v5bmi v5menr v5menl v2wototr v2wototl v3wototr v3wototl v3bmi v5wototr v5wototl Right_A_Baseline Left_A_Baseline 跨度>
  • %>%pivot_longer(!c(id, sex, age, mostid, race, Right_A_Baseline, Left_A_Baseline), names_to = c("Time", ".value"), names_pattern = "[az ](\\d)([A-Za-z]{3,})")
  • 现在效果很好。我非常感谢你。我非常感谢你,这是一次很棒的学习。大概你的代码的新部分意味着 [A-Za-z] 任何值大写或没有大写字母?
【解决方案2】:

为了完整起见,这里是使用melt() 和新的measure() 函数的解决方案:

library(data.table) # development version 1.14.1 used here
TrialDataLong <- 
  melt(setDT(TrialData), measure.vars = measure(time, value.name, pattern = "v(\\d)(\\w+)"))
TrialDataLong 
   id sex time pase dep
1:  1   M    0   10 Yes
2:  2   F    0   15  No
3:  1   M    1   12 Yes
4:  2   F    1   15 Yes
5:  1   M    2   14 Yes
6:  2   F    2   16 Yes
7:  1   M    3   13 Yes
8:  2   F    3   16 Yes

重新排序以便更好地与 OP 的预期结果进行比较:

TrialDataLong[order(id, time)]
   id sex time pase dep
1:  1   M    0   10 Yes
2:  1   M    1   12 Yes
3:  1   M    2   14 Yes
4:  1   M    3   13 Yes
5:  2   F    0   15  No
6:  2   F    1   15 Yes
7:  2   F    2   16 Yes
8:  2   F    3   16 Yes

数据

library(data.table)
TrialData <- fread("
id sex v0pase v1pase v0dep v1dep v2pase v3pase v2dep v3dep
 1   M     10     12   Yes   Yes     14     13   Yes   Yes
 2   F     15     15    No   Yes     16     16   Yes   Yes")

【讨论】:

  • 由于某种原因,当我这样做时,它说“测量”功能不存在。我有最新版本的 data.table。
  • @JamesLancaster,请仔细检查版本号。您是否安装了 development 版本 1.14.1,它在 CRAN 上not 可用?请参阅github.com/Rdatatable/data.table/wiki/Installation 了解安装开发 版本的说明。谢谢。
【解决方案3】:

您可以将tidyr::pivot_longernames_tonames_pattern 参数一起使用。

tidyr::pivot_longer(TrialData, 
                    cols = -c(id, sex),
                    names_to = c('Time', '.value'), 
                    names_pattern = 'v(\\d+)([a-z]+)')

#     id sex   Time   pase dep  
#  <dbl> <chr> <chr> <dbl> <chr>
#1     1 M     0        10 Yes  
#2     1 M     1        12 Yes  
#3     1 M     2        14 Yes  
#4     1 M     3        13 Yes  
#5     2 F     0        15 No   
#6     2 F     1        15 Yes  
#7     2 F     2        16 Yes  
#8     2 F     3        16 Yes  

【讨论】:

  • 非常感谢。所以我可以为未来学习并适应它,你能向我解释一下这部分'v(\\ d +)([a-z] +)'吗?我在网上找不到明确的解释。
  • 这个正则表达式中有两个捕获组。 (\\d+)v 之后的一位或多位数字。该值位于Time 列中。 [a-z]+ 是数字之后的另一个字符值。因为我们在这里使用.value,所以它有自己的列。在这个例子中是pasedep
猜你喜欢
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2017-03-10
相关资源
最近更新 更多