使用单独的数据框模板中定义的格式创建数据框

时间:2018-03-28 11:11:51

标签: r dataframe

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

例如我有一个空白模板

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'中的'level 4',那么当转换为正确的格式时,它应该被NA替换

3 个答案:

答案 0 :(得分:6)

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

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
}

答案 1 :(得分:3)

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

我们为type制作了例外(因为他们的factorstype),我们将相关的integer分配给新修改的列。

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

答案 2 :(得分:1)

假设您有一个模板,您可以为特定的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。