【问题标题】:Create dataframe using formats defined in seperate dataframe template使用在单独的数据框模板中定义的格式创建数据框
【发布时间】:2018-03-28 11:11:50
【问题描述】:

我正在创建多个数据框,我希望每个数据框中的列与我创建的空白数据框模板中指定的类型相同

例如我有一个空白模板

template <- data.frame(
  char = character(),
  int = integer(),
  fac1 = factor(levels = c('level1', 'level2', 'level3')),
  fac2 = factor(levels = c('level4', 'level5')),
  stringsAsFactors = FALSE
)

然后我想创建一些数据框,但想保持模板格式的列(即 char 是一个字符,fac2 是一个具有两个级别“level4”和“level5”的因子)

df1 <- data.frame(
  char = c('a', 'b'),
  int = c(1,2),
  fac1 = c('level2', 'level1'),
  fac2 = c('level4', 'level4')
)

df2 <- data.frame(
  char = c('c', 'd'),
  int = c(3,4),
  fac1 = c('level3', 'level4'),
  fac2 = c('level5', 'level4')
)

当我创建df1df2 时,我可以明显地指定列类型,但我想避免多次输入相同的内容,例如,如果水平发生变化,我只想要一个因素在一个地方改变它。

如果在不是级别的因素之一中创建了一个值(例如,上面“df2”中的“fac1”中的“级别 4”,则在转换为正确格式时应将其替换为 NA

【问题讨论】:

  • 如果检查str(template)char 不是character。你需要stringsAsFactors = FALSE

标签: r dataframe


【解决方案1】:

也许您可以对数据框进行后处理:

df_template <- function(...) {
  df <- data.frame(...)
  df$char <- as.character(df$char)
  df$int  <- as.integer(df$int)
  df$fac1 <- factor(df$fac1, levels = c('level1', 'level2', 'level3'))
  df$fac2 <- factor(df$fac2, levels = c('level4', 'level5'))
  df
}

【讨论】:

    【解决方案2】:

    我们可以创建一个检查模板每一列的type 的函数,并使用as.* 函数将相关data.frame 的相应列强制转换为相关type

    我们将factors 设为例外(因为他们的typeinteger),我们将相关的levels 分配给新修改的列。

    Map 获取模板列并成对输入,然后将输出(list)转换为data.frame

    format_df <- function(df,template) {
      as.data.frame(
        Map(function(x,y) {
          if(is.factor(x))
            factor(y,levels(x))
          else
            match.fun(paste0("as.",typeof(x)))(y)
            # or `class<-`(y,class(x)) , same effect for given example
        },template,df),
        stringsAsFactors = FALSE)
    }
    
    
    df1b <- format_df(df1,template)
    # char int   fac1   fac2
    # 1    a   1 level2 level4
    # 2    b   2 level1 level4
    
    str(df1b)
    # 'data.frame': 2 obs. of  4 variables:
    # $ char: chr  "a" "b"
    # $ int : int  1 2
    # $ fac1: Factor w/ 3 levels "level1","level2",..: 2 1
    # $ fac2: Factor w/ 2 levels "level4","level5": 1 1
    

    注意输出中的level5

    【讨论】:

      【解决方案3】:

      假设您有一个模板,您可以为特定的 data.frame 创建一种构造函数。

      例如,

      .TEMPLATE <- data.frame(
        char = character(),
        int = integer(),
        fac1 = factor(levels = c('level1', 'level2', 'level3')),
        fac2 = factor(levels = c('level4', 'level5')),
        stringsAsFactors = FALSE
      )
      
      df_constructor <- function(...) {
        df <- as.data.frame(...)
        within(df, {
          char <- as(char, class(.TEMPLATE$char)),
          int <- as(int, class(.TEMPLATE$int)),
          fac1 <- factor(fac1, levels(.TEMPLATE$fac1)),
          fac1 <- factor(fac1, levels(.TEMPLATE$fac2)),
          stringsAsFactors = FALSE
        })
      }
      

      vapply 函数具有 FUN.VALUE 参数,您可以在其中传递用于构建返回值的模板。但我不确定vapply 是否适用于 data.frames。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-06
        • 1970-01-01
        • 2021-09-29
        • 2013-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多