Reputation: 53
I am having a list with dataframes and want to test if the dataframes include certain fields; if not these fields should be created (as blank field), when the field exists it should do nothing (leave the values unchanged).
Example:
List1 <- list(
DF1 = data.frame("x"=c("A","B","C"),
"y"=c("D","E","F"),
"z"=c("G","H","I" )
),
DF2 = data.frame("t"=c("K","L","M"),
"y"=c("D","E","F"),
"z"=c("G","H","I" )
)
)
On these dataframes I want to test if field "s" and "t" exist. Field "s" should be created in DF1 and DF2, Field "t" should be created only in DF1.
I tried the creation of separate functions (one for "s" and one for "t" but wasn't able to get it working properly. Furthermore I wonder if I can do all the test in one function. See below the structure of the function I tried (for "s")
Existence_col_s <- function(id) {
if( !("s" %in% colnames(id)))
mutate(id, s = "")
else {do nothing}
}
List2 <- lapply(List1, c(Existence_col_s, Existence_col_t))
Any ideas?
Upvotes: 0
Views: 99
Reputation: 3412
Here's a base solution:
A callback to check and add columns:
checkAdd <- function(df,cols) {
for(col in cols) {
if(is.null(df[[col]])) df[[col]] <- ''
}
return(df)
}
Your lapply:
lapply(List1, checkAdd, cols= c('s','t'))
Upvotes: 1
Reputation: 3388
Helper function to conditionally add a column to a data.frame:
library(tidyverse)
add_column = function(df, col) {
if (!col %in% names(df)) df[[col]] = ''
df
}
Apply this function twice to each element of List1:
map(List1, function(df) {
df %>% add_column('s') %>% add_column('t')
})
Upvotes: 1