Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "Apply", Add new column to dataframe in list where value is also stored in list in R

Tags:

r

I have two lists of identical length, one that stores some dataframes and one that stores character strings. I am trying to figure out how to add a new column to each dataframe that contains the corresponding value in the list of characters. For example:

#Staring Dataframes
df1 <- data.frame(v1 = c(1,2,3),
                  v2 = c("a","b","c"))
df2 <- data.frame(v1 = c(7,8,9),
                  v2 = c("x","y","z"))

dflist <- list(df1, df2)

#List containing values to add to each dataframe
nameslist <- c('first df value', 'second df value')

#Desired output 
df1$v3 <- nameslist[1]

  v1 v2    v3
 1  a first df value
 2  b first df value
 3  c first df value

df2$v3 <- nameslist[2]

 v1 v2       v3
 7  x second df value
 8  y second df value
 9  z second df value

It seems like this would be easy enought to do with a loop, but how would I accomplish this using one of the "apply" functions?

I have tried the following:

output <- lapply(seq_along(dflist), function(i) dflist[[i]]$test = nameslist[[i]])
#This returns a list of character vectors coresponding to nameslist
output <- mapply(function(df, name) df$test = name, dflist, nameslist)
#Returns a single character vector of the values in nameslist

I feel like one of the above must be reasonably close. If anyone could provide any guidance on this it would be much appreciated. TIA.

like image 379
reidj Avatar asked Sep 02 '25 16:09

reidj


2 Answers

Use Map here

Map(cbind, dflist, v3 = nameslist)

-output

[[1]]
  v1 v2             v3
1  1  a first df value
2  2  b first df value
3  3  c first df value

[[2]]
  v1 v2              v3
1  7  x second df value
2  8  y second df value
3  9  z second df value

with mapply, SIMPLIFY = TRUE, by default, also, have to return the data if we are doing the assignment <-

mapply(function(df, name) {df$test = name;df}, dflist, nameslist, SIMPLIFY= FALSE)
[[1]]
  v1 v2           test
1  1  a first df value
2  2  b first df value
3  3  c first df value

[[2]]
  v1 v2            test
1  7  x second df value
2  8  y second df value
3  9  z second df value
like image 189
akrun Avatar answered Sep 05 '25 08:09

akrun


We could use lapply

lapply(seq_along(dflist), function(i) {
  cbind(dflist[[i]], v3 = nameslist[i])
})

[[1]]
  v1 v2             v3
1  1  a first df value
2  2  b first df value
3  3  c first df value

[[2]]
  v1 v2              v3
1  7  x second df value
2  8  y second df value
3  9  z second df value
like image 39
TarJae Avatar answered Sep 05 '25 10:09

TarJae