本着与@TommyFlyn 给出的答案相同的精神,还有labelled
由 Joseph Larmarange 维护的包,特别是由 Daniel Ludecke ( sjlabelled
) 和 Hadley Wickham 编写的。
假设df.ls
,使用 导入的数据框列表haven::read_dta
,它们有很多共同的变量,但不是全部。在这种情况下,使用它很方便,dplyr::bind_rows
它不需要在所有数据帧中具有相同的变量(列)。正如OP所提到的,问题在于它“删除”了标签。我要补充一点,这仅适用于列表的数据框共有的变量。当某些变量在某些数据框中但不在其他数据框中时,它们会保留其标签。
我们可以使用
common_col_names <- ## get the names of the columns common to all the dfs
Reduce(intersect, lapply(df.ls,names))
library(labelled)
labs.ls <- ## a list of lists
lapply(
df.ls,
function(x) {
labelled::var_label(
x[, common_col_names],
unlist = FALSE
)
}
)
假设给定变量在所有数据帧中保持相同的标签df.ls
。因此,使用common_col_names
以及标签是恒定的假设意味着 的所有元素(列表)labs.ls
都是相同的。
设置unlist = FALSE
(默认)允许在列表(而不是字符向量)中有不同的标签,这反过来又允许以下(来自labelled
文档): name 将匹配数据框的一列将被考虑在内。如果 value 是字符向量,则标签应与 data.frame 的列的顺序相同。'' 如果列表的所有数据帧中的列/变量不相同,这将非常方便。
请注意,检查labs.ls
对于检查标签是否在数据帧中实际上保持相同很有用。
然后,您只需绑定列表中的不同数据框并分配提取的标签:
df <- dplyr::bind_rows(df.ls)
labelled::var_label(df) <- labs.ls[[1]]
这里我们使用labs.ls[[1]]
,但是由于我们只考虑所有数据帧共有的变量,并且我们假设这些变量的标签是恒定的,请注意可以使用 2、3、...,length(df.ls)
而不是 1。