R:在组和子组中切片数据帧记录的最有效方法(通过目录和 CSV)

R: Most efficient way to slice data frame records in groups and sub-groups (via directories and CSV)

给定以下示例数据 (R data frame),我想为每个组创建文件夹,包含每个子组的文件夹,(最终)包含一个具有相应值的 CSV 文件 val1 , 使用 R.

Grp <- c("A", "A", "A", "B", "B", "B")
Subgrp <- c("k", "l", "m", "n", "n", "n")
val1 <- c(1.1, 3.2, 4.5, 5.6, 6.7, 7.7)
df <- data.frame(Grp, Subgrp, val1)

这是我迄今为止尝试过的方法,为每个子组创建一个 CSV 文件。

by(df, df$Subgrp, FUN=function(i) write.csv(i,paste0("C:/Temp/",i$Subgrp[1], ".csv")))

我需要为大数据框迭代这个。实现这一目标的最有效方法是什么?我愿意接受基于循环和 dpyr 的建议。

你很接近。

我的解读:

  • "为每个组创建文件夹,包含每个子组的文件夹":使用 .../A/k.../B/n
  • 等目录
  • "具有相应值的 CSV 文件 val1":保存为 CSV 时从框架中删除 GrpSubgrp 列. (如果不是这个,则将 subset(...) 替换为下面的 i。)
basepath <- "c:/Temp"

# pre-create directories
for (p in unique(file.path(basepath, df$Grp, df$Subgrp))) dir.create(p, recursive = TRUE)

by(df, df$Subgrp, FUN=function(i) {
  write.csv(subset(i, select = -c(Grp, Subgrp)),
            file.path(basepath, i$Grp[1], i$Subgrp[1], "value.csv"),
            row.names = FALSE)
})
# df$Subgrp: k
# NULL
# ------------------------------------------------------------ 
# df$Subgrp: l
# NULL
# ------------------------------------------------------------ 
# df$Subgrp: m
# NULL
# ------------------------------------------------------------ 
# df$Subgrp: n
# NULL

lf <- list.files(".", pattern = "csv$", recursive = TRUE, full.names = TRUE)
lf
# [1] "./A/k/value.csv" "./A/l/value.csv" "./A/m/value.csv" "./B/n/value.csv"

read.csv(lf[1])
#   val1
# 1  1.1

由于 by 的 return 值无关紧要,您可以将其包装在 invisible(.) 中或捕获并忽略输出 ign <- by(..).

我宁愿使用lapply这样你可以方便地使用子组的名称。

lapply(df$Subgrp, \(x) write.csv(subset(df, Subgrp == x), file=sprintf('C:/Temp/%s.csv', x)))

使用 tidyverse:

df %>%
  unite(file, Grp, Subgrp, sep='/')%>%
  group_by(file = paste0(file, '.csv'))%>%
  summarise(write.csv(cur_data(), 
          if(dir.exists(dirname(file[1]))) file[1]
          else {dir.create(dirname(file[1]),recursive = T);file[1]},row.names = FALSE))