Mary Rachel
Mary Rachel

Reputation: 331

Issues using gsub to rename multiple columns

I have a dataset from a Qualtrics survey that has a form-field formatted question that split the responses into multiple columns, all identically named with the question text except for the form field text (ie. "What is your contact information? - Name"; "What is your contact information - Phone Number", etc.). I want to rename them by removing the text preceding the dash and just leaving the form field names.

Since they're all named with the same naming conventions, I figured that the most efficient method would be to use gsub() to replace "What is your contact information - " with a blank. I'm struggling to figure out the right code that will rename the columns (not create new ones) by identifying the ones with the pattern in their names, using contains(), case_when(), if_any(), and other relative functions. Everytime I try a different combination with gsub, I get errors like the one below. I tried to define the colnames as the X in gsub() but struck out. Where am I going wrong?

# Attempted Code

## Reproducible Example ##

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))

## Attempt 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.

## Attempt 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.

## Attempt 3

data<- test%>%
 rename(setNames(paste0(names(.)), gsub("What is your contact info? - ","",names(.))))

## No error code, but the names of the columns weren't changed ##

Upvotes: 2

Views: 67

Answers (3)

Friede
Friede

Reputation: 7410

I would go with

names(test) = sub(".*- ", "", names(test))

similiar recommended in a comment below your question; giving

> test
   Name   City    State     Gender Group
1  John Austin    Texas       Male     1
2 Jacob Helena  Montana Non-Binary     2
3  Jess Albany New York     Female     3

or if needed with

i = grepl("What is your contact info? - ", names(test), fixed=TRUE)
names(test)[i] = sub(".*- ", "", names(test)[i])
rm(i)

Upvotes: 3

Rui Barradas
Rui Barradas

Reputation: 76402

Also possible, inspired in this answer but with the meta-character fix.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

test %>%
  rename_with(gsub, 
         pattern = "What is your contact info\\? - ", 
         replacement = "",
         contains("What is your contact info"))
#> # A tibble: 3 × 5
#>   Name  City   State    Gender     Group
#>   <chr> <chr>  <chr>    <chr>      <int>
#> 1 John  Austin Texas    Male           1
#> 2 Jacob Helena Montana  Non-Binary     2
#> 3 Jess  Albany New York Female         3

Created on 2024-11-19 with reprex v2.1.1

Upvotes: 2

ThomasIsCoding
ThomasIsCoding

Reputation: 101335

You should use fixed = TRUE, otherwise ? in the pattern will be treated as a optional quantifier in regex

test %>%
    rename_with(~ gsub("What is your contact info? - ", "", .x, fixed = TRUE), contains("What is your contact info? - "))

or even shorter (with matches instead of contains)

test %>%
    rename_with(~ gsub(".*- ", "", .x), matches(".*- "))

such that

# A tibble: 3 × 5
  Name  City   State    Gender     Group
  <chr> <chr>  <chr>    <chr>      <int>
1 John  Austin Texas    Male           1
2 Jacob Helena Montana  Non-Binary     2
3 Jess  Albany New York Female         3

Upvotes: 3

Related Questions