Лучший способ переименовать переменные, соответствующие различным шаблонам именования, чтобы обозначать время согласованным образом? - PullRequest
0 голосов
/ 16 марта 2020

У меня есть широкий набор данных, который имеет психометрию c меры, взятые у участников в разные моменты времени.

Метки, изменяющиеся во времени в психометрии c меры имеют вид: QuestionnaireTime_Item#. Например, dass1_1, где dass = Questionnaire, 1_ = Time_. и 1 = Item# соответствующей анкеты.

Это в большинстве случаев согласуется с анкетами, однако есть одна психометрическая переменная, которая не следует этой номенклатуре: siss1. Хотя эта номенклатура согласуется с другими переменными, обозначающими дату и номер сеанса сбора данных, т.е. date1 и session1. Как видно, метки для этих переменных находятся на концах переменных. Тем не менее, существует ряд переменных, которые содержат цифру в имени, которые не должны быть изменены, в частности cff1, cff2, et c., Которые обозначают номер элемента по этой мере, а не по времени (однако они задаются только один раз в течение периода сбора datefinal [см. ниже]).

Время в именах переменных в большинстве случаев обозначается цифрами (1–14), за исключением слова «окончательный» (например, datefinal, sessionfinal, dassfinal_1, sissfinal) для последнего сеанса. Кроме того, существует период сбора данных, который проходил через 6 и 12 месяцев после последнего сеанса 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 или 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))

1 Ответ

2 голосов
/ 16 марта 2020

Спасибо за репрезентацию и подробное объяснение вашей проблемы. Если я правильно понял, следующая процедура должна дать вам то, что вы ищете или, если это не удастся, надеюсь, вы достаточно близко.

Я использовал два раунда 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"
...