重命名匹配不同命名模式的变量以一致的方式表示时间的最佳方法?

Best way to rename variables matching different naming patterns to denote time in consistent manner?

我有一个广泛的数据集,其中包含从参与者那里获得的心理测量数据 跨越不同的时间点。

心理测量中随时间变化的标签采用以下形式: QuestionnaireTime_Item#。 一个例子是 dass1_1 其中 dass = Questionnaire, 1_ = Time_ 进行了问卷调查;和相关问卷的 1 = Item#

这在所有问卷中基本一致,但是有一个心理测量 不遵循此命名法的变量:siss1。虽然这 命名法与表示日期和 session 的其他变量一致 数据数量 collection 即 date1session1。 可以看出,这些变量的标签位于变量的末尾。 但是,有许多名称中包含不应更改的数字的变量,特别是 cff1cff2 等,表示此度量的项目编号而不是时间(但是,他们只在 datefinal collection 期间被问过一次 [见下文])。

变量名中的时间在大多数情况下(1--14)用数字表示,单词除外 'final'(例如,datefinalsessionfinaldassfinal_1sissfinal)最后一个 session。 此外,还有一个数据 collection 期发生在最后一个 session datefinal 数据 collection 期之后的 6 个月和 12 个月。 这些用 6fup12fup 表示,例如 date_6fupdass6fup_2.

我想更改表示时间变量的字符串以使其保持一致 并将它放在每个变量名的开头。另外,我想在问卷名称和相关项目编号之间加一条下划线。 例如:

鉴于表示时间的数值,最好的方法是什么 变化和不一致?

目前,我有下面提供的 here:

names(old_sp_wide) <- sub("([a-z]+)(\d+)(_\d+)?", "T\2.\1\3",
                          sub("final", "15", names(old_sp_wide)),
                          ignore.case = TRUE
                          )

但是,这也会更改带有 cff 前缀的变量的名称,并且不会像预期的那样在带有时间标签 6fup12fup 的变量上工作。

鉴于表示时间的数值发生变化并且不一致,最好的方法是什么?有没有办法用 stringrstringi?

请参阅下面的可重现示例。

structure(list(uci = 12345L, dob = structure(1L, .Label = "1988_01_26", class = "factor"),
               sex = 2L, sp_episode = 1L, staff = structure(1L, .Label = "aj", class = "factor"),
               YP_consent = 1L, date1 = structure(1L, .Label = "2016_10_03", class = "factor"),
               session1 = 1L, dass1_1 = 3L, dass1_2 = 0L, dass1_3 = 2L,
               siss1 = 1L, diag1 = NA, diag2 = NA, diag3 = NA, pastpsyc = NA,
               pastmed = NA, date2 = structure(1L, .Label = "2016_10_15", class = "factor"),
               session2 = 3L, dass2_1 = 3L, dass2_2 = 0L, dass2_3 = 2L,
               siss2 = NA, datefinal = structure(1L, .Label = "2016_11_12", class = "factor"),
               sessionfinal = 8L, dassfinal_1 = 2L, dassfinal_2 = 1L, dassfinal_3 = 2L,
               dassfinal_4 = 3L, sissfinal = NA, cff1 = NA, cff2 = NA, cff3 = NA,
               date_6fup = structure(1L, .Label = "2014_06_30", class = "factor"),
               dass6fup_2 = 3L, dass6fup_3 = 1L, dass6fup_4 = 1L, siss6fup = 2L,
               date_12fup = NA), class = "data.frame", row.names = c(NA,
                                                                     -1L))

感谢您的代表和对您问题的详尽解释。如果我理解正确的话,下面的例程应该能给你你想要的东西,或者,如果失败了,希望你能很接近。

我用了两轮stringr::str_replace_all。在第一轮中,我们将所有 final6fup12fup 后缀替换为它们指定的等效数字(即 15、16、17)。在第二轮中,我们针对剩余的两个主要正则表达式模式,确保排除任何以 cff 前缀开头的匹配项。

# create new_names by applying two rounds of str_replace_all to the old names
new_names <- names(df) %>%
  stringr::str_replace_all(c(
    'final' = '15',
    '_6fup|6fup' = '16',
    '_12fup|12fup' = '17'
  )) %>%
  stringr::str_replace_all(
    c(
      '^(?!cff\d)(^[A-z]+)(\d{1,2})$' = 'T\2.\1',
      '^(?!cff\d)(^[A-z]+)(\d{1,2})_(\d)' = 'T\2.\1_\3'
    )
  ) 

# compare old names to new names
new_names %>% purrr::set_names(names(df))
#>           uci           dob           sex    sp_episode         staff 
#>         "uci"         "dob"         "sex"  "sp_episode"       "staff" 
#>    YP_consent         date1      session1       dass1_1       dass1_2 
#>  "YP_consent"     "T1.date"  "T1.session"   "T1.dass_1"   "T1.dass_2" 
#>       dass1_3         siss1         diag1         diag2         diag3 
#>   "T1.dass_3"     "T1.siss"     "T1.diag"     "T2.diag"     "T3.diag" 
#>      pastpsyc       pastmed         date2      session2       dass2_1 
#>    "pastpsyc"     "pastmed"     "T2.date"  "T2.session"   "T2.dass_1" 
#>       dass2_2       dass2_3         siss2     datefinal  sessionfinal 
#>   "T2.dass_2"   "T2.dass_3"     "T2.siss"    "T15.date" "T15.session" 
#>   dassfinal_1   dassfinal_2   dassfinal_3   dassfinal_4     sissfinal 
#>  "T15.dass_1"  "T15.dass_2"  "T15.dass_3"  "T15.dass_4"    "T15.siss" 
#>          cff1          cff2          cff3     date_6fup    dass6fup_2 
#>        "cff1"        "cff2"        "cff3"    "T16.date"  "T16.dass_2" 
#>    dass6fup_3    dass6fup_4      siss6fup    date_12fup 
#>  "T16.dass_3"  "T16.dass_4"    "T16.siss"    "T17.date"