在数据框列表中有条件地创建字段

时间:2020-01-06 15:04:02

标签: r function lapply

我有一个包含数据框的列表,想测试数据框是否包含某些字段;如果不是,则应创建这些字段(作为空白字段),如果该字段存在,则不应执行任何操作(保留值不变)。

示例:

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" )
  )
) 

在这些数据帧上,我想测试字段“ s”和“ t”是否存在。字段“ s”应在DF1和DF2中创建,字段“ t”应仅在DF1中创建。

我尝试创建单独的函数(一个用于“ s”,一个用于“ t”,但无法使其正常工作。此外,我想知道是否可以在一个函数中进行所有测试。请参见下文)我尝试过的函数的结构(用于“ 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))

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

Helper函数有条件地将一列添加到data.frame:

library(tidyverse)
add_column = function(df, col) {
  if (!col %in% names(df)) df[[col]] = ''
  df
}

将此函数两次应用于List1的每个元素:

map(List1, function(df) {
  df %>% add_column('s') %>% add_column('t')
})

答案 1 :(得分:1)

这是一个基本解决方案:

用于检查和添加列的回调:

checkAdd <- function(df,cols) {
  for(col in cols) {
    if(is.null(df[[col]])) df[[col]] <- ''
  }
  return(df)
}

您的快乐:

lapply(List1, checkAdd, cols= c('s','t'))