使用gsub重命名多列时遇到的问题及解决方案咨询
问题描述
我有一份来自Qualtrics问卷的数据集,其中表单格式的问题将响应拆分为多列,列名统一为「问题文本 - 表单字段名」(例如"What is your contact info? - Name"、"What is your contact info? - City"等)。我希望移除短横线前的文本,仅保留表单字段名。
我想用gsub()把"What is your contact info? - "替换为空值来实现,但尝试结合contains()、rename()等函数的多种组合都出了问题,以下是我的尝试及遇到的错误:
尝试的代码及问题
# 可复现代码示例 test<- structure(list(`What is your contact info? - Name` = c("John", "Jacob", "Jess"), `What is your contact info? - City` = c("Austin", "Helena", "Albany"), `What is your contact info? - State` = c("Texas", "Montana", "New York"), Gender = c("Male", "Non-Binary", "Female" ), Group = 1:3), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -3L)) ## 尝试1 data<- test%>% mutate(across(contains("What is your contact info? - "), gsub("What is your contact info? - ",""))) # 错误信息: # Error in `mutate()`: # ℹ In argument: `across(...)`. # Caused by error in `gsub()`: # ! argument "x" is missing, with no default # Error in `mutate()`: # ℹ In argument: `across(...)`. # Caused by error in `across()`: # ! `.fns` must be a function, a formula, or a list of functions/formulas. ## 尝试2 data<- test%>% rename(contains("What is your contact info? - "), gsub("What is your contact info? - ","")) # 错误信息: # Error in `rename()`: # ℹ In argument: `gsub("What is your contact info? - ", "")`. # Caused by error in `gsub()`: # ! argument "x" is missing, with no default # Run `rlang::last_trace()` to see where the error occurred. ## 尝试3 data<- test%>% rename(setNames(paste0(names(.)), gsub("What is your contact info? - ","",names(.)))) # 无报错,但列名未更改
错误原因分析
- 尝试1:
mutate()的作用是修改列的内容,不是重命名列。而且across()要求传入的函数必须是完整的函数、公式或函数列表,你直接调用gsub()却没指定要处理的对象(x参数),语法完全错误。 - 尝试2:
rename()的正确语法是新列名 = 旧列名的键值对形式,你传入的参数不符合函数要求,且gsub()同样缺失必要的x参数。 - 尝试3:
setNames()的参数顺序搞反了,正确顺序是setNames(对象, 新名称),你把旧名称和新名称弄反了,导致重命名无效。
正确实现方法
推荐使用dplyr的rename_with()函数,它专门用于批量重命名列,搭配contains()筛选目标列,再用gsub()处理列名:
library(dplyr) # 针对特定问题文本的写法 data <- test %>% rename_with( ~ gsub("What is your contact info? - ", "", .x), contains("What is your contact info? - ") ) # 查看重命名后的列名 names(data) # [1] "Name" "City" "State" "Gender" "Group"
如果你的数据集里有多个不同问题文本的表单列,可以用更通用的正则表达式写法,自动匹配所有" - "分隔的列名,提取后面的字段名:
data <- test %>% rename_with( ~ gsub(".* - ", "", .x), matches(" - ") )
正则表达式".* - "会匹配从列名开头到最后一个" - "的所有内容,替换为空后就只剩下后面的表单字段名,适用性更广。
内容的提问来源于stack exchange,提问作者Mary Rachel
相关产品推荐
相关产品推荐

