拆分每个变量的数据帧列表

问题描述 投票:0回答:1

我有 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)])
  }
}
r split
1个回答
0
投票

您可以创建一个函数,将 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
© www.soinside.com 2019 - 2024. All rights reserved.