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
Number of Months Between Two Dates
Reshape Multiple Values At Once
Idiomatic R Code For Partitioning a Vector by an Index and Performing an Operation on That Partition
How to Convert Long to Wide Format With Counts
Yaml Current Date in Rmarkdown
Basic Lag in R Vector/Dataframe
Replace Missing Values With Column Mean
How to Convert Posix Date to Day of Year
Convert Comma Separated String to Numeric Columns
Changing Column Names in a List of Data Frames in R
How to Add Layers in Ggplot Using a For-Loop
Make a Group_Indices Based on Several Columns