Adding a New Column to Each Element in a List of Tables or Data Frames

Adding a new column to each element in a list of tables or data frames

An alternate solution is to use cbind, and taking advantage of the fact that R will recylce values of a shorter vector.

For Example

x <- df2  # from above
cbind(x, NewColumn="Singleton")
# x y NewColumn
# 1 4 d Singleton
# 2 5 e Singleton
# 3 6 f Singleton

There is no need for the use of rep. R does that for you.

Therfore, you could put cbind(filelist[[i]], ID[[i]]) in your for loop or as @Sven pointed out, you can use the cleaner mapply:

filelist <- mapply(cbind, filelist, "SampleID"=ID, SIMPLIFY=F)

Add a new column in each table of a list, and fill it with the name of the table

We could use map2. Here we create first a vector with the number of dataframes in the list in this example 1:3. In your original example 1:25:

library(purrr)

my_list <- list(table1,table2, table3)
ID <- 1:3

map2(my_list, ID, ~cbind(.x, ID = .y))
[[1]]
A B ID
1 x y 1
2 x y 1
3 x y 1

[[2]]
A B ID
1 x y 2
2 x y 2
3 x y 2

[[3]]
A B ID
1 x y 3
2 x y 3
3 x y 3

Adding a column to every dataframe in a list with the name of the list element

there is no need to mutate just bind using dplyr's bind_rows

library(tidyverse)
my.list %>%
bind_rows(.id = "groups")

Obviously requires that the list is named.

Lapply to Add Columns to Each Dataframe in a List

Use Map. It is short for mapply(..., SIMPLIFY = FALSE) as suggested by Ari.

df1 <- data.frame(x = runif(3), y = runif(3))
df2 <- data.frame(x = runif(3), y = runif(3))
dfs <- list(df1, df2)
years <- list(2013, 2014)

Map(cbind, dfs, year = years)
# [[1]]
# x y year
# 1 0.8843945 0.6285246 2013
# 2 0.8400041 0.1369520 2013
# 3 0.4398870 0.4660476 2013
#
# [[2]]
# x y year
# 1 0.4153315 0.5831114 2014
# 2 0.9685105 0.2398060 2014
# 3 0.9507591 0.7585670 2014

How do I add a column to each data frame in a list

Here is an approach with base R only:

lapply(mylist, transform, ratio = y / y[1])
# [[1]]
# time y ratio
# 1 1 2 1.0
# 2 2 3 1.5
# 3 3 6 3.0
#
# [[2]]
# time y ratio
# 1 1 3 1.000000
# 2 2 4 1.333333
# 3 3 7 2.333333

It might be easier to understand when written as

lapply(mylist, function(x) transform(x, ratio = y / y[1]))

Also, see ?transform.

Add column containing data frame name to a list of data frames

Your list is unnamed. You can either make it named manually while creating it

my_list = list(data = data, data2 = data2, data3 = data3)

Or you can use mget & ls combination if you have many data sets

my_list <- mget(ls(pattern = "^data$|^data\\d+$"))

Afterwords, just use Map

my_list <- Map(cbind, my_list, new_clumn = names(my_list))
my_list
# $data
# column1 column2 new_clumn
# 1 12 27 data
# 2 27 987 data
# 3 378 1234 data
#
# $data2
# column1 column2 new_clumn
# 1 12 27 data2
# 2 27 987 data2
# 3 378 1234 data2
#
# $data3
# column1 column2 new_clumn
# 1 12 27 data3
# 2 27 987 data3
# 3 378 1234 data3

#If you want to put the data sets back to the global environment you can use `list2env`
#list2env(my_list, .GlobalEnv)
#Please Note that it is usually not the preffered practice to move data frames to the global environment and back. It is preferred to store all you data sets in list from the very beginning and manipulating them within the list using functions such as `Map`, `lapply`, etc.

Get the name of the list object then add that name as a new column of the each list

If I've understood you correctly, I'd probably use the purrr library. imap_dfr will pass both your matrix and its name to the function, and then bind the results into a single dataframe.

library(purrr)

new_list <- imap_dfr(mylist, function(mat, name) {
result <- as.data.frame(mat)
result$name <- name
result
})

gives

> new_list
Analyte_Mean SDBetweenGroup SDWithinGroup replicates NumSamples FValue PValue FCritical name
1 5.1210 0.008363944 0.01994994 5 10 1.8788386 0.0836504 2.124029 SiO2
2 2.0812 0.005310367 0.01590597 5 10 0.4426877 0.9032892 2.124029 Al2O3

Dataframe name to column in list of dataframes using purrr

Another way is to use lst instead of list which automatically names the list for you with imap which uses these names directly (.y).

library(tidyverse)
my_list <- lst(batch_1, batch_2, batch_3)
purrr::imap(my_list, ~mutate(.x, batch = .y))

# $batch_1
# A B batch
# 1 1 4 batch_1
# 2 2 5 batch_1
# 3 3 6 batch_1

# $batch_2
# A B batch
# 1 1 4 batch_2
# 2 2 5 batch_2
# 3 3 6 batch_2

# $batch_3
# A B batch
# 1 1 4 batch_3
# 2 2 5 batch_3
# 3 3 6 batch_3

Add a column to data frame as a list of data frames

We could get the datasets into a list with mget

# // initialize a list column
x$test <- vector('list', nrow(x))
# // loop over the sequence of rows of dataset
for(i in seq_len(nrow(x))) {
# // create string with index
str1 <- paste0('df', i, '_', 1:3)
# // get the value of the objects from string with mget
tmplist <- mget(str1)
# // assign it to the corresponding list element of test
x$test[[i]] <- tmplist
}


Related Topics



Leave a reply



Submit