1

I realise I asked two separate questions in my last post and had one of them answered by very clever peeps super quickly.

Obviously I still can't wrap my head around data frame lists or lapply!

I have csv list of original questions and renamed questions. In this example, I am trying to write the code to update Q.1a to Q.1 as per the Qs data frame.

df1 <- data.frame("ID" = 1, "Q.1" = 2, Q1.1 = 3)
df2 <- data.frame("ID." = 2, "Q.1a" = 3, Q1.1 = 4)


dflist <- lapply(ls(), function(x) if (class(get(x)) == "data.frame") get(x))
dflist <- Filter(length, dflist)


Qs  <- data.frame("Original.Name" = "Q.1a", "New.Name" = "Q.1")

The tables look like this: I want to update Q.1a as per the Qs table

  ID Q.1a Q1.1
1  1    2    3

  ID. Q.1 Q1.1
1   2   3    4

  Original.Name New.name
1           Q.1a      Q.1

The code I am trying to write to rename the questions that is currently full of errors, I am sure the piping is not supposed to be there!

lapply(dflist, function(x) {
  names(x) <- names (x) %in%
  Qs$Original.name = Qs$New.name[match(names(x)[names(x) %in% Qs$Original.name],
         Qs$Original.name)]
})

Can anyone point me in the right direction? Thanks so much.

Edited to show expected output where Q1a from the original example above has been upated to Q1.

  ID Q.1 Q1.1
1  1   2    3
  ID. Q.1 Q1.1
1   2   3    4

Ideally I want to be able to match and replace the column names from the Qs table. The original column name replaced with new column name

4
  • What is your expected output? dflist has column names ID Q1 Q11 and ID Q1a Q11 what should it change to? Commented May 25, 2020 at 6:11
  • Ah thanks for the question. The real data is wide and has lots of columns. The CSV has the original column names and the new column names. This table is Qs. In this example the original question Q1a in the df needs to be Q1. Commented May 25, 2020 at 6:35
  • So what I want to do is write a match function across all the data frames that matches the new column name to the old one and updates all data frames Commented May 25, 2020 at 6:36
  • I've edited to be clearer about expected output Commented May 25, 2020 at 6:42

1 Answer 1

1

You can use ifelse with match to get new names of the columns.

dflist <- lapply(dflist, function(x) {
   names(x) <- ifelse(names(x) %in% Qs$Original.Name, 
                      Qs$New.Name[match(names(x), Qs$Original.Name)], names(x))
   x
})

dflist
#[[1]]
#  ID Q.1 Q1.1
#1  1   2    3

#[[2]]
#  ID. Q.1 Q1.1
#1   2   3    4
Sign up to request clarification or add additional context in comments.

5 Comments

depending on your default.stringsAsFactors() settings, you may have to set stringsAsFactors = FALSE when creating the Qs data.frame to make it work
> df1 <- data.frame("ID" = 1, "Q.1a" = 2, Q1.1 = 3) > df2 <- data.frame("ID." = 2, "Q.1" = 3, Q1.1 = 4) > > > dflist <- lapply(ls(), function(x) if (class(get(x)) == "data.frame") get(x)) > dflist <- Filter(length, dflist) > > > > Qs <- data.frame("Original.Name" = "Q.1a", "New.Name" = "Q.1") > > dflist <- lapply(dflist, function(x) { + names(x) <- ifelse(names(x) %in% Qs$Original.Name, + Qs$New.Name[match(names(x), Qs$Original.Name)], names(x)) + x + }) > > dflist [[1]] ID 1 Q1.1 1 1 2 3 [[2]] ID. Q.1 Q1.1 1 2 3 4
Wierdly I get 1 instead of Q.1. I am sure I copied it right!
Yes, that's what @starja is talking about. Use Qs <- data.frame("Original.Name" = "Q.1a", "New.Name" = "Q.1", stringsAsFactors = FALSE)
Yay thanks so much I tried that but I should have cleared the environment and run it all againg.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.