Use a for loop to rename variables in data frames

Viewed 357

I have the following data which I have split by name into separate data frames. After I run the following code, the variables in each data set are automatically named "X..i..".

I would like to rename the variable of each separate data frame so it matches the data set.

# load data
df1_raw <- data.frame(name = c("A", "B", "C", "A", "C", "B"), 
                      start = c(1, 3, 4, 5, 2, 1),  
                      end = c(6, 5, 7, 8, 6, 7)) 
df1 <- split(x = df1_raw, f = df1_raw$name) # split data by name
df1 <- lapply(df1, function(x) Map(seq.int, x$start, x$end)) # generate sequence intervals
df1 <- map(df1, unlist) # unlist sequences
df1 <- lapply(df1, data.frame) # convert to df

# rename variables
name <- c("A", "B", "C")

for (i in seq_along(df1)) {
  names(df1[i]) <- name[i]
}

The last for loop does not work to rename variables. When I type names(df1$A) I still get "X..i..". The output I would like from names(df1$A) is "A".

Does anyone have any thoughts on how to rename these variables? Thanks!

2 Answers

You need to use [[]] when indexing from a list

for (i in seq_along(df1)) {
  names(df1[[i]]) <- name[i]
}

Alternatively you could change how you create the list so you don't have to rename after the fact

df1 <- split(x = df1_raw, f = df1_raw$name) # split data by name
df1 <- lapply(df1, function(x) Map(seq.int, x$start, x$end)) # generate sequence intervals
df1 <- map(df1, unlist) # unlist sequences
df1 <- Map(function(x,name) {as.data.frame(setNames(list(x), name))}, df1, names(df1))

I think the solution by @MrFlick is enough for addressing the issue of renaming within a for loop.

Here is a base R workaround that may work for you

lapply(
  split(df1_raw, df1_raw$name),
  function(x) {
    with(
      x,
      setNames(
        data.frame(unlist(mapply(seq, start, end))),
        unique(name)
      )
    )
  }
)

which gives

$A
   A
1  1
2  2
3  3
4  4
5  5
6  6
7  5
8  6
9  7
10 8

$B
   B
1  3
2  4
3  5
4  1
5  2
6  3
7  4
8  5
9  6
10 7

$C
  C
1 4
2 5
3 6
4 7
5 2
6 3
7 4
8 5
9 6
Related