co7000
co7000

Reputation: 221

Replacing Column Name with Loop in R

I have three df P1,P2,P3 with each three columns. I want to change the second column from each df to D1, D2, D3 with a loop but nothing is working. What do I miss out?

C1 <- c(12,34,22)
C2 <- c(43,86,82)
C3 <- c(98,76,25)

C4 <- c(12,34,22)
C5 <- c(43,86,82)
C6 <- c(98,76,25)

C7 <- c(12,34,22)
C8 <- c(43,86,82)
C9 <- c(98,76,25)

P1 <- data.frame(C1,C2,C3)
P2 <- data.frame(C4,C5,C6)
P3 <- data.frame(C7,C8,C9)

x <- c("P1", "P2", "P3")
b <- c("D1","D2","D3")

for (V in b){
  names(x)[2] <- "V"
}

The output I would expect is:

P1 <- data.frame(C1,D1,C3)
P2 <- data.frame(C4,D2,C6)
P3 <- data.frame(C7,D3,C9)

Upvotes: 1

Views: 53

Answers (2)

user10917479
user10917479

Reputation:

It is usually best to work with lists for this type of thing. That can make life easier and is generally a good workflow to learn.

list1 <- list(P1 = P1, P2 = P2, P3 = P3)

# here is your loop
for (i in seq_along(list1)) {
  names(list1[[i]])[2] <- b[i]
}

# you can use Map as well for iteration, similar to @akrun's solution
# this is really identical at this point, except you've created the list differently
Map(function(df, b) {names(df)[2] <- b; df}, list1, b)

Upvotes: 1

akrun
akrun

Reputation: 887831

We can use mget to get the values of the string vector in a list, use Map to rename the second column each of the list element with the corresponding 'b' value, then use list2env to update those objects in the global env

list2env(Map(function(x, y) {names(x)[2] <- y; x}, mget(x), b), .GlobalEnv)

-output

P1
#  C1 D1 C3
#1 12 43 98
#2 34 86 76
#3 22 82 25

P2
#  C4 D2 C6
#1 12 43 98
#2 34 86 76
#3 22 82 25
P3
#  C7 D3 C9
#1 12 43 98
#2 34 86 76
#3 22 82 25

For understanding the code, first step is mget on the vector of strings

mget(x)

returns a list of data.frame

Then, we are passing this as argument to Map along with the corresponding 'b' vector. i.e. each element of list is a unit, similarly each element of vector is a unit

Map(function(x, y) x, mget(x), b)

The function(x, y) is anonymous/lambda function construct. Using that we set the names of the second column to that of 'b'. Here, the anonymous argument for 'b' is 'y'. Later, we wrap everything in list2env as it is a named list and it will look up for those names in the global env to update it

Upvotes: 1

Related Questions