Условное создание полей в списке фреймов данных - PullRequest
0 голосов
/ 06 января 2020

У меня есть список с фреймами данных, и я хочу проверить, содержат ли фреймы данных определенные поля; если нет, то эти поля должны быть созданы (как пустое поле), когда поле существует, оно не должно делать ничего (оставить значения без изменений).

Пример:

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 ]

1 голос
/ 06 января 2020

Вот базовое решение:

Обратный вызов для проверки и добавления столбцов:

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

Ваше счастье:

lapply(List1, checkAdd, cols= c('s','t'))
1 голос
/ 06 января 2020

Вспомогательная функция для условного добавления столбца в 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')
})

...