learneR
learneR

Reputation: 53

Conditional creation of fields in a list of dataframes r

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

Answers (2)

SmokeyShakers
SmokeyShakers

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

Kent Johnson
Kent Johnson

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

Related Questions