【问题标题】:R Function to Subset, Aggregate, Pivot, and Save Data Frames用于子集、聚合、透视和保存数据帧的 R 函数
【发布时间】:2020-10-13 19:58:52
【问题描述】:

我在编写函数时遇到问题:

我有一个我想要的 df (a) subset,只保留所需的列,(b) aggregate 基于两个分组变量(“日期”和“城市”)的“x”值,(c)pivot_wider,和(d)write.csv。最终,我需要为 14 个变量和两个分组参数执行此操作,我认为这是使用用户定义函数的好时机。

这里是示例数据:

> print(head(data, 5))
# A tibble: 5 x 23
    fn    zip5   group cluster area    fy  week   date      urban   FN0   FN1
  <int>   <dbl> <chr> <fct>   <ord> <dbl> <fct> <date>     <ord>  <dbl> <dbl>
1 584000   NA    1    LOCAT~   Nort~  2019 00B   NA         urba~    3    NA
2 584000   NA    1    LOCAT~   Nort~  2019 01B   2018-09-29 urba~    20   37
3 584000   NA    2    LOCAT~   Sout~  2019 02B   2018-10-06 rura~    5    3
4 584000   NA    2    LOCAT~   Sout~  2019 03B   2018-10-13 rura~    NA   NA
5 584000   NA    3    LOCAT~   East~  2019 04B   2018-10-20 subu~    13   19

这里是dput():

> dput(droplevels(wkhr4_W[2282334:2282341, c("fn", "date", "urban", "FN2")]))
structure(list(fn = c(150929L, 150929L, 150927L, 150927L, 150927L, 
150927L, 150927L, 150927L), date = structure(c(18412, 18419, 
NA, 17803, 17810, 17817, 17824, 17831), class = "Date"), urban = structure(c(1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Suburban", "Not Avaliable"
), class = c("ordered", "factor")), FN2 = c(1625, 1911, NA, NA, 
NA, NA, NA, NA)), row.names = c(NA, -8L), class = c("tbl_df", 
"tbl", "data.frame"))

这是我目前所拥有的:

save_file = function(x, y, data) {
  file <- print(paste0("wkhr_2020_", x, "_", y))
  df <- subset(data, date >= "2020-01-04" & date <= "2020-06-06", select = c(date, fn, y, x))
  file <- aggregate(as.formula(paste(x, "~ date +", y)), FUN = sum, data = df)
  file <- pivot_wider(file, values_from = x, names_from = y)
  write.csv(file, paste0("./Work Hours/", file, ".csv"), row.names = FALSE)
}

save_file("FN0", "urban", data)

是否有人对如何执行此操作有建议?

【问题讨论】:

  • 欢迎来到 SO!您愿意提供data 的样本,以便获得最佳答案吗?尝试使用dput(head(data)) 并使用输出编辑问题。
  • 您的 xy 不会在聚合公式中进行评估 - 请改用 aggregate(as.formula(paste(x, "~ date +", y)), ...)。我还强烈建议将data 作为参数包含在内,这样您就可以在任何数据帧上使用它,而不管它是否被命名为data
  • @Ben - 感谢您的建议。由于公司政策,我无法发布数据(以任何形式),但我在我的问题中添加了head(data, 5) 输出的编辑版本。 @GregorThomas - 我更改了帖子中的代码以反映您的建议。代码现在给出一个错误:错误:不能对不存在的列进行子集化。 x 81 列不存在。
  • 您能与dput分享您编辑的数据吗?它使复制/粘贴变得更加容易。如果您的因素有很多级别,dput(droplevels(data[1:10, ])) 效果很好。
  • @GregorThomas - 令人沮丧的是,我无法发布 dput() 输出,因为它包含专有数据。公司政策。

标签: r function dataframe syntax


【解决方案1】:

主要问题是您在 subset 行中 - select = c(date, fn, y, x) 混合了 datefn (它们是文字的、不带引号的列名)和 y, x ,它们是值是列名的对象。你不能这样混搭。更改为 select = c("date", "fn", y, x) 即可解决问题。

pivot_wider 的最新版本中,您应该使用all_of() 来处理值为列名的对象,因此我也进行了更改。

最后,您首先构建文件名并将其命名为file,但随后覆盖了该文件名,并将修改后的数据命名为file。我为数据保留df,为文件名保留file。我还将您的print() 更改为message(),在某些情况下它可能更友好,例如如果您想在不更改功能的情况下将其静音,它可能会以不同的颜色打印,这样更容易扫描为。

save_file = function(x, y, data) {
  file = paste0("wkhr_2020_", x, "_", y)
  message(file)
  df <- subset(data, date >= "2020-01-04" & date <= "2020-06-06", select = c("date", "fn", y, x))
  df <- aggregate(as.formula(paste(x, "~ date +", y)), FUN = sum, data = df)
  df <- pivot_wider(df, values_from = all_of(x), names_from = all_of(y))
  write.csv(file, paste0("./Work Hours/", file, ".csv"), row.names = FALSE)
}

【讨论】:

    猜你喜欢
    • 2016-11-19
    • 2020-02-17
    • 2018-02-22
    • 2018-07-08
    • 2019-11-17
    • 1970-01-01
    • 2014-11-10
    • 2019-06-12
    • 1970-01-01
    相关资源
    最近更新 更多