5

dplyr::bind_rows結合しようとしている dfs に因子列が存在する場合の警告を回避する、より高度なバージョンを作成したいと考えてUnequal factor levels: coercing to characterいます (非因子列も含まれる場合があります)。次に例を示します。

df1 <- dplyr::data_frame(age = 1:3, gender = factor(c("male", "female", "female")), district = factor(c("north", "south", "west")))
df2 <- dplyr::data_frame(age = 4:6, gender = factor(c("male", "neutral", "neutral")), district = factor(c("central", "north", "east")))

次にbind_rows_with_factor_columns(df1, df2)戻ります(警告なし):

dplyr::data_frame(
  age = 1:6,
  gender = factor(c("male", "female", "female", "male", "neutral", "neutral")),
  district = factor(c("north", "south", "west", "central", "north", "east"))
)

これが私がこれまでに持っているものです:

bind_rows_with_factor_columns <- function(...) {
  factor_columns <- purrr::map(..., function(df) {
      colnames(dplyr::select_if(df, is.factor))
  })

  if (length(unique(factor_columns)) > 1) {
      stop("All factor columns in dfs must have the same column names")
  }

  df_list <- purrr::map(..., function (df) {
    purrr::map_if(df, is.factor, as.character) %>% dplyr::as_data_frame()
  })

  dplyr::bind_rows(df_list) %>%
    purrr::map_at(factor_columns[[1]], as.factor) %>%
    dplyr::as_data_frame()
}

キャラクターに要因を強制する必要を潜在的に回避するためにパッケージを組み込む方法について誰かがアイデアを持っているかforcats、または同じ機能を維持しながらこれのパフォーマンスを向上させるための一般的な提案を誰かが持っているかどうか疑問に思っています (私は構文に固執しtidyverseます)。ありがとう!

4

2 に答える 2

1

友人からの素晴らしい解決策に基づいて、私自身の質問に答えます。

bind_rows_with_factor_columns <- function(...) {
  purrr::pmap_df(list(...), function(...) {
    cols_to_bind <- list(...)
    if (all(purrr::map_lgl(cols_to_bind, is.factor))) {
      forcats::fct_c(cols_to_bind)
    } else {
      unlist(cols_to_bind)
    }
  })
}
于 2017-02-16T15:42:25.223 に答える