Pivot_longer 用于多列重复测量数据

问题描述

我正在尝试使用 pivot_longer 包中的 dplyr 函数将我的数据转换为长格式。当前广泛的数据包括对患者年龄、收缩压以及是否使用降压药物 (med_hypt) 以及时间不变的“性别”变量的 3 次重复测量。

示例数据和我尝试过的:

library(tidyverse)
library(dplyr)
library(magrittr)

wide_data <- structure(list(id = c(12002,17001,17002,42001,66001,82002,166002,177001,177002,240001),sex = structure(c(2L,1L,2L,1L),.Label = c("men","women"),class = "factor"),time1_age = c(71.2,67.9,66.5,57.7,57.1,60.9,80.9,59.7,58.2,66.6),time1_systolicBP = c(102,152,NA_real_,170,151,135,162,133,131,117),time1_med_hypt = c(0,0),time2_age = c(74.2,69.2,67.8,58.9,58.4,62.5,82.2,61,59.5,67.8),time2_systolicBP = c(NA_real_,146,129,137,144,132),time2_med_hypt = c(0,time3_age = c(78,74.2,72.8,64.1,63.3,67.7,87.1,66,64.5,72.9),time3_systolicBP = c(NA_real_,160.5,171,160,166,150.5),time3_med_hypt = c(0,0)),row.names = c(NA,10L),class = "data.frame")

# Pivoting to a longer format
long_data <- wide_data %>% 
  pivot_longer(
    cols=!id,names_to=c(".value","time"),names_sep="_",values_drop_na=FALSE
  )

这会产生以下tibble:

# A tibble: 40 x 6
      id time       sex   time1 time2 time3
   <dbl> <chr>      <fct> <dbl> <dbl> <dbl>
 1 12002 NA         women  NA    NA    NA  
 2 12002 age        NA     71.2  74.2  78  
 3 12002 systolicBP NA    102    NA    NA  
 4 12002 med        NA      0     0     0  
 5 17001 NA         men    NA    NA    NA  
 6 17001 age        NA     67.9  69.2  74.2
 7 17001 systolicBP NA    152   146   160. 
 8 17001 med        NA      0     0     0  
 9 17002 NA         women  NA    NA    NA  
10 17002 age        NA     66.5  67.8  72.8
# ... with 30 more rows

我想要的是列名是 id、时间、年龄、性别、systolicBP 和 med_hypt。每位患者 3 行,对应 3 次重复测量。

有什么帮助吗?

解决方法

这可能不会为已经发布的解决方案添加任何新内容,唯一的区别是用于 <label>Enter ID</label> <input id="id"> <button id="btn">Get attendance</button> <ul id="list"></ul> 参数的 regex

  • 如果您注意到某些列名称以一个 names_pattern 分隔,而其他列名称以两个 _ 分隔。 _ 捕获任何单词字符,现在如果我指定我们在此后面有一个数字,\\w+ 就像 \\d+ 中的 time3,我们告诉 time3_age 存储这个pivot_longer 列中对应于 time3 的列名的一部分。然后其余的列名用于我们尝试测量的变量名,行 timeagesystolicBP
  • 需要注意的是,如果我们使用 med_hypt 而不是 \\w+\\d+,则无论是 \\w+ 带下划线还是 med_hypt 不带下划线,其余部分都会被捕获为列名.但是如果我们只使用 systolicBP 它也可以捕获 med 并且结果列将是 \\w+ 而不是 hypt
  • 最后,因为我定义了两个捕获组,所以我必须以某种方式定义 med_hyptnames_pattern,以指定如何定义和分隔它们中的每一个。
names_sep
,

由于某些列名称中有多个下划线,因此最好使用 light 而不是 names_patternnames_sep 允许我们传递灵活的正则表达式模式以从列名中捕获。

names_pattern
,

如果我理解正确

   wide_data %>% 
      pivot_longer(
        cols=-c(id,sex),names_to=c(".value","time"),names_sep = "_",values_drop_na=FALSE
      )

# A tibble: 30 x 6
      id sex   time       time1 time2 time3
   <dbl> <fct> <chr>      <dbl> <dbl> <dbl>
 1 12002 women age         71.2  74.2  78  
 2 12002 women systolicBP 102    NA    NA  
 3 12002 women med          0     0     0  
 4 17001 men   age         67.9  69.2  74.2
 5 17001 men   systolicBP 152   146   160. 
 6 17001 men   med          0     0     0  
 7 17002 women age         66.5  67.8  72.8
 8 17002 women systolicBP  NA    NA    NA  
 9 17002 women med          0     0     0  
10 42001 men   age         57.7  58.9  64.1