我有 13 个数据框的列表。我需要将每个数据帧分成几个数据帧。 id 列(每个数据帧有多个)应保留在所有生成的数据帧中。除了 id 列之外,每个结果数据帧只需要一个变量。例如,如果 df1 有 3 个 id 列和 6 个其他变量,我将有 6 个数据框,每个数据框包括 4 列:3 个 id 列和 1 个变量。我应该对列表中的所有数据框执行此操作。 这是一个虚拟示例:
obj1 <- list(bodyPart = c("leg", "arm", "knee"),side = c("LEFT", "RIGHT", "LEFT"), device = c("LLI", "LSM", "GHT"), length = c(12, 476, 7), id = c("AA", "BB", "CC"), mwID = c("a12", "k87", "j98")) %>% as.data.frame()
obj2 <- list(bodyPart = c("ankel", "ear", "knee"), side = c("LEFT", "LEFT", "LEFT"), device = c("GOM", "LSM", "YYY"), id = c("ZZ", "DD", "FF"), tqID = c("kj8", "ll23", "sc26")) %>% as.data.frame()
x <- list(foo = obj1, bar = obj2)
所需的输出如下所示:
obj1_1 <- list(id = c("AA", "BB", "CC"), mwID = c("a12", "k87", "j98"), bodyPart = c("leg", "arm", "knee")) %>% as.data.frame()
obj1_2 <- list( id = c("AA", "BB", "CC"), mwID = c("a12", "k87", "j98"), length = c(12.43, 476, 7.14)) %>% as.data.frame()
obj1_3 <- list(side = c("LEFT", "RIGHT", "LEFT"), id = c("AA", "BB", "CC"), mwID = c("a12", "k87", "j98")) %>% as.data.frame()
.
.
.
obj2_1 <- list(id = c("ZZ", "DD", "FF"), tqID = c("kj8", "ll23", "sc26"), bodyPart = c("ankel", "ear", "knee")) %>% as.data.frame()
.
.
.
此后,我需要将每个数据帧保存为 csv 文件,不包括所有 NA 行。 我已经尝试应用我在另一篇文章中找到的解决方案,但陷入其中(按列拆分数据帧并在每个子集中保留一组公共列)。我非常感谢您对此的帮助。 根据前面提到的帖子中提供的解决方案,我应该首先从每个数据帧中取出 id 列,然后指定每个数据帧要分割成的部分数量。我遇到的第一件事是如何达到所需的水平来显示每个数据帧的变量数量,因为分割数量就是变量数量。我写了一个for循环,但我不确定问题出在哪里。
id_cols <- c("id", "mwID", "tqID")
var_cols <- list()
df_parts <- list()
for (table_name in names(x)) {
var_cols[[table_name]] <- x[[table_name]] %>%
select(-c(id, ends_with('ID')))
for (var_name in names(var_cols)) {
print(var_name)
n_parts[[table_name]] <- length(var_cols[[table_name]])
df_parts <- split(
var_cols,
cut(
seq_along(var_cols),
n_parts[[table_name]],
labels = FALSE
)
) |>
lapply(\(v) x[, c(id_cols, v)])
}
}
您可以创建一个函数,将 data.frame 列表作为输入,并为列表中的每个 data.frame 应用一个选择函数
[
:
split_list <-
function(l, n = 2){
# For each data.frame,
lapply(l, \(data){
#Count the number of columns, assuming the number of columns to keep is `n` (2 by default),
#and they are located at the end of the data.frame
nc = ncol(data)
lsel <- lapply(1:(nc-n), \(x) c(x, (nc-n+1):NC))
#Apply the `[` function on the set of selecting indices defined above
lapply(lsel, \(col) data[col])
})
}
split_list(x)
# $foo
# $foo[[1]]
# bodyPart id mwID
# 1 leg AA a12
# 2 arm BB k87
# 3 knee CC j98
#
# $foo[[2]]
# side id mwID
# 1 LEFT AA a12
# 2 RIGHT BB k87
# 3 LEFT CC j98
#
# $foo[[3]]
# device id mwID
# 1 LLI AA a12
# 2 LSM BB k87
# 3 GHT CC j98
#
# $foo[[4]]
# length id mwID
# 1 12 AA a12
# 2 476 BB k87
# 3 7 CC j98
#
#
# $bar
# $bar[[1]]
# bodyPart id tqID
# 1 ankel ZZ kj8
# 2 ear DD ll23
# 3 knee FF sc26
#
# $bar[[2]]
# side id tqID
# 1 LEFT ZZ kj8
# 2 LEFT DD ll23
# 3 LEFT FF sc26
#
# $bar[[3]]
# device id tqID
# 1 GOM ZZ kj8
# 2 LSM DD ll23
# 3 YYY FF sc26