我有多个相似的数据集(例如,每年一个),但是每个变量的命名约定都不同。对于单个数据框来说,这是一个非常简单的任务,但是我正在寻找一种可扩展到许多数据集的方法。
我的方法是使用主查询表或“数据字典”,以便将所有数据合并到单个数据帧中。 我已经抽象了一个简单的例子。
我首选的工作流程通常是将数据存储在“列表列”中,并使用purrr
对每个数据集执行相同的任务。
问题-我当前的解决方案如下,但我想知道:
这是我将使用的查找表:
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.
答案 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))])