R中的变量名称模式匹配不一致

时间:2017-10-01 22:53:32

标签: r

我有一个包含大量不一致命名变量的数据集。 df1中捕获的当前命名的功能,以及df2中的所需名称。我想要的是将变量名称(例如(initial_salary_D1_H1))更改为(initialsalary_D1_H1),换句话说,对于要移除的_D1_H1子字符串之前的任何非字/非数字字符。

_D1_H1模式,即_ + anyletter + anynumber,出现在大多数变量名称的末尾,尽管它出现的次数各不相同。它可能出现零次(Date.of.Birth),两次(Employee_Date_Start_D1_H1)或三次(Employee_Gender_g2_D1_H1)。

这种模式在某些变量名称(lunch_p5_type_canteen1_D1_H1)的开头具有额外的难度。

最后,在某些变量名称中,模式的前一个字符是一个单词(all.new.Staff_D2_H4),在某些变量名称中是一个数字(dept_Preferences2_D1_H8)。

df1 <- data.frame(Date.of.Birth=c(1,1,1),initial_salary_D1_H1=c(1,1,1),Employee_Gender_g2_D1_H1=c(1,1,1),Employee_Date_Start_D1_H1=c(1,1,1),dept_Preferences2_D1_H8=c(1,1,1),ini_InterviewShortlist2_D1_H6 =c(1,1,1),Retentionpercentage_D7_H19=c(1,1,1),all.new.Staff_D2_H4=c(1,1,1),all_old_D3_H13=c(1,1,1),lunch_p5_type.canteen_D1_H1=c(1,1,1),all_EmploymentStatus4_D2_H11=c(1,1,1))
df2 <- data.frame(DateofBirth=c(1,1,1),initialsalary_D1_H1=c(1,1,1),EmployeeGender_g2_D1_H1=c(1,1,1),EmployeeDateStart_D1_H1=c(1,1,1),deptPreferences2_D1_H8=c(1,1,1),iniInterviewShortlist2_D1_H6 =c(1,1,1),Retentionpercentage_D7_H19=c(1,1,1),allnewStaff_D2_H4=c(1,1,1),allold_D3_H13=c(1,1,1),lunchp5typecanteen_D1_H1=c(1,1,1),allEmploymentStatus4_D2_H11=c(1,1,1))
names(df1)
names(df2)

我一直在努力,但我对模式匹配完全陌生。使用substring()和gsub()一个选项?

substring(names(df1), regexpr("*_\w\d$i*", names(df1)) - 1)

感谢您的帮助!

更新

如何将其粘贴在函数中并将输出保存为数据框(我有三个数据框)?

1 个答案:

答案 0 :(得分:1)

应该有一个较小的版本但我认为它可以完成这项工作

paste0(
    gsub("[_.]", "", gsub("(.*[a-zA-Z]{2,}[0-9]*).*", "\\1", names(df1))), 
    gsub(".*[a-zA-Z]{2,}[0-9]*", "", names(df1)))

<强>解释

此部分gsub("(.*[a-zA-Z]{2,}[0-9]*).*", "\\1", names(df1))将所有字​​符保持在两个至少两个字符和零个或多个数字结束的位置。让我们称之为X

此部分gsub("[_.]", "", X)_

中移除.X

,最后一部分只替换X

将所有内容粘贴在一起

更新

在函数中使用它并将输出保存为数据框

normalize_names <- function(df){

  if(!(class(df1) == "data.frame")) stop("Object not a data.frame")

  new_names <- paste0(
    gsub("[_.]", "", gsub("(.*[a-zA-Z]{2,}[0-9]*).*", "\\1", names(df))), 
    gsub(".*[a-zA-Z]{2,}[0-9]*", "", names(df)))

  names(df) <- new_names
 df

}

实施例

df1 <- normalize_names(df1)
df_list <- lapply(list(df1, df2, df3), normalize_names)