mindlessgreen
mindlessgreen

Reputation: 12142

Add column with variable column name to dataframes in a list

I have a list of data.frames.

l <- list("a"=data.frame(a=1:2,b=1:2),"b"=data.frame(a=1:2,b=1:2))
l
$a
a b
1 1 1
2 2 2

$b
a b
1 1 1
2 2 2

I am trying to add a column to each of those data.frames. The name of the column is defined in a variable.

I tried this and it didn't work.

j=1
lapply(l,function(x) x[[paste0("Column",LETTERS[j])]] <- 0)

I have split up the above to be more readable. But this doesn't work either.

cname <- paste0("Column",LETTERS[j])
fun1 <- function(x,y) x[[y]] <- 0
lapply(l,fun1,cname)

The cbind approach works with lapply(), but I am not quite sure how to add a column name through variable. This also shows the output I am looking for.

lapply(l,function(x) cbind(x,ColumnA=0))

$a
  a b ColumnA
1 1 1       0
2 2 2       0

$b
  a b ColumnA
1 1 1       0
2 2 2       0

Perhaps someone has a better suggestion.

Upvotes: 1

Views: 72

Answers (4)

Ronak Shah
Ronak Shah

Reputation: 389325

We can use transform and use setNames to change column name

lapply(l, function(x) setNames(transform(x, temp = 0), c(names(x), cname)))

#$a
#  a b ColumnA
#1 1 1       0
#2 2 2       0

#$b
#  a b ColumnA
#1 1 1       0
#2 2 2       0

Or also change only the last column name

lapply(l, function(x) {transform(x, temp = 0);names(x)[ncol(x)] <- cname;x})

Upvotes: 0

G. Grothendieck
G. Grothendieck

Reputation: 270318

Apply replace to each component of l with the indicated arguments.

lapply(l, replace, paste0("Column", LETTERS[j]), 0)

giving:

$a
  a b ColumnA
1 1 1       0
2 2 2       0

$b
  a b ColumnA
1 1 1       0
2 2 2       0

Update

Revised.

Upvotes: 1

kstew
kstew

Reputation: 1114

Using plyr...

llply(l,function(x) data.frame(x,c=0))
$a
  a b c
1 1 1 0
2 2 2 0

$b
  a b c
1 1 1 0
2 2 2 0

Upvotes: 1

akrun
akrun

Reputation: 887951

One option to assign on the lhs would be with := and evaluate (!!) the string in tidyverse

library(purrr)
library(dplyr)
j <- 1
map(l, ~ .x %>% 
           mutate(!! str_c("Column",LETTERS[j]) := 0))
#$a
#  a b ColumnA
#1 1 1       0
#2 2 2       0

#$b
#  a b ColumnA
#1 1 1       0
#2 2 2       0

Or in base R, modify the fun1 to return the dataset after the assignment

fun1 <- function(x,y) {x[[y]] <- 0; x}
cname <-  paste0("Column",LETTERS[j])
lapply(l, fun1, y = cname)
#$a
#  a b ColumnA
#1 1 1       0
#2 2 2       0

#$b
#  a b ColumnA
#1 1 1       0
#2 2 2       0

Upvotes: 2

Related Questions