r - 重命名与不同命名模式匹配的变量以一致方式表示时间的最佳方法?
问题描述
我有一个广泛的数据集,其中包含来自不同时间点的参与者的心理测量。
心理测量中的时变标签采用以下形式:
QuestionnaireTime_Item#
. 一个例子是dass1_1
= dass
, Questionnaire
=1_
进行Time_
了问卷调查;和1
=Item#
相关问卷。
这在整个问卷调查中基本一致,但是有一个心理测量变量不遵循此命名法:siss1
. 尽管此命名法与表示数据收集的日期和会话数的其他变量一致,即, date1
和session1
。可以看出,这些变量的标签位于变量的末尾。但是,有许多变量的名称中包含不应更改的数字,特别cff1
是 ,cff2
等,它们表示此度量上的项目编号而不是时间(但是,它们仅在datefinal
收集期间被询问一次 [见下文])。
在大多数情况下,变量名称中的时间由数字表示 (1--14),但最后一个会话的单词“final”(例如,、、、、)datefinal
除外。此外,还有一个数据收集期,发生在最后一次会议数据收集期后的 6 个月和 12 个月。这些用或表示,例如, 和。sessionfinal
dassfinal_1
sissfinal
datefinal
6fup
12fup
date_6fup
dass6fup_2
我想更改表示时间变量的字符串以使其一致并将其放在每个变量名称的开头。此外,我想在问卷名称和相关项目编号之间添加一个下划线。例如:
date1
->T1.date
session1
->T1.session
siss2
->T2.siss
dass1_1
->T1.dass_1
datefinal
->T15.date
dass_6fup_2
->T16.dass_2
date_12fup
->T17.date
鉴于表示时间的数值发生变化并且不一致,最好的方法是什么?
目前,我有以下内容:
names(old_sp_wide) <- sub("([a-z]+)(\\d+)(_\\d+)?", "T\\2.\\1\\3",
sub("final", "15", names(old_sp_wide)),
ignore.case = TRUE
)
但是,这也会更改带有前缀的变量的名称,并且在带有时间标签和cff
的变量上无法按预期工作。6fup
12fup
鉴于表示时间的数值发生变化并且不一致,最好的方法是什么?有没有办法用stringr
or解决这个问题stringi
?
请参阅下面的可重现示例。
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
。在第一轮中,我们将所有final
、6fup
和12fup
后缀替换为它们指定的等效数字(即 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"
推荐阅读
- xpath - Google Sheets IMPORTXML XPath 帮助(了解如何阅读页面源代码)
- python - Python中的匹配间隔(纬度/经度)和时间
- kotlin - 获取对调用函数的类的引用
- mysql - 检查 MySQL 数据库中的多个重复项
- winapi - 是否有预先存在的 WinAPI 来检查 some_app.exe 是否可以在不提供完整路径的情况下运行并在任何时候运行它
- java - hibernate 和persistence.xml 的问题
- python - 使用分类变量的 Kmeans
- r - R中有没有办法将组内的各种项目转换为多列?
- angular - Angular 8 - 在不访问 URL 参数的情况下跟踪显示的组件
- c# - Visual Studio 2017 Entity Framework 6.2.0 模型浏览器打开但为空白