使用查找表(或数据字典)重命名多个data_frames的变量

时间:2018-08-21 17:27:09

标签: r purrr

我有多个相似的数据集(例如,每年一个),但是每个变量的命名约定都不同。对于单个数据框来说,这是一个非常简单的任务,但是我正在寻找一种可扩展到许多数据集的方法。

我的方法是使用主查询表或“数据字典”,以便将所有数据合并到单个数据帧中。 我已经抽象了一个简单的例子。

我首选的工作流程通常是将数据存储在“列表列”中,并使用purrr对每个数据集执行相同的任务。

问题-我当前的解决方案如下,但我想知道:

  1. 有没有一种方法可以使用单个主查询表来做到这一点? (我在示例末尾的尝试失败)
  2. 对于有人可以建议的这个常见问题,是否有更好的解决方案/常规工作流程。

这是我将使用的查找表:

lookup_table <-
  tribble(~Var, ~newvarname,
          "mpg", "mpg",
          "cyl", "cyl",
          "CYLINDERS", "cyl",
          "disp", "disp",
          "DISPLACEMENT", "disp",
          "hp", "hp",
          "HORSEPOWER", "hp")

变量名称不匹配的示例数据:

mt_list <- 
  data_frame(testcase = 1:3,
             data =list(rename(head(mtcars[, 1:4]), CYLINDERS = "cyl"), 
                        rename(tail(mtcars[, 1:4]), HORSEPOWER = "hp"), 
                        rename(mtcars[13:18, 1:4], DISPLACEMENT = "disp")),
             lookup = list(lookup_table, lookup_table, lookup_table))

如果运行此代码,则可以了解为什么它行不通...数据集不共享公共变量名。

mt_list %>% 
  select(data) %>% 
  unnest() %>% head(5)

# A tibble: 5 x 7
    mpg CYLINDERS  disp    hp   cyl HORSEPOWER DISPLACEMENT
  <dbl>     <dbl> <dbl> <dbl> <dbl>      <dbl>        <dbl>
1  21           6   160   110    NA         NA           NA
2  21           6   160   110    NA         NA           NA
3  22.8         4   108    93    NA         NA           NA
4  21.4         6   258   110    NA         NA           NA
5  18.7         8   360   175    NA         NA           NA

到目前为止我发现的最佳解决方案:

mt_list <- 
  mt_list %>% 
  mutate(data = map2(.$data, mt_list$lookup, 
                     ~setNames(.x, .y$newvarname[match(names(.x), .y$Var)])))

然后可以取消嵌套。

当我尝试使用单个主查询表时,出现错误。我已经通过将表复制到数据框的每一行来解决了上面的问题,但这可能会导致问题。

mt_list %>% 
  mutate(data = map2(.$data, lookup_table, 
                     ~setNames(.x, .y$varname[match(names(.x), .y$Var)])))

Error in mutate_impl(.data, dots) : 
Evaluation error: `.x` (3) and `.y` (2) are different lengths.

1 个答案:

答案 0 :(得分:1)

如果数据集相似(即,相同数量的变量和列顺序),则应执行以下操作:

# create a list of data frames (no need for your complicated nested structure)
dfs <- mt_list$data # alternatively: dfs <- list(df1, df2, df3)

# store the desired variable names
varnames <- c("mpg", "cyl", "disp", "hp")

# set the variable names across the list of data frames
dfs <- lapply(dfs, function(x) setNames(x, varnames))

如果变量在数据帧中的顺序不同,则可以在应用上述解决方案之前按列名对列进行排序:

dfs <- lapply(dfs, function(x) x[ , order(names(x))])