【问题标题】:How to iterate and make new variables within a function in R? [duplicate]如何在 R 中的函数中迭代和创建新变量? [复制]
【发布时间】:2018-08-03 05:55:50
【问题描述】:

在 R 中有没有办法创建一个函数,将子集(例如按日期)放入它自己的数据框?例如,我有 30 天的数据,我想将每一天分解为单独的日子并将其输出到一个新的单独数据框中。我不知道如何在函数中做到这一点。有什么线索吗?

示例: 数据框:df_of_month

通过各种循环函数所需的输出:

df_of_month_day1
df_of_month_day2
df_of_month_day3
df_of_month_day4
df_of_month_day5
df_of_month_day6

等等?....我一直在寻找多种方式的沙子,但它不起作用。

【问题讨论】:

  • 强烈建议您不要这样做。而是在dplyr 中查看group_by,或者至少将这些数据帧存储为列表的元素。
  • 也许您正在寻找类似split() 的东西?拆分 data.frame 的结果将是一个 data.frames 列表。
  • 您可以轻松地使用lapply/sapply(...)assign() 函数来构造变量名;请参阅assign() 上的现有问题。但这比简单地创建一个数组df_of_month_day[1:6] 更糟糕。除非你能清楚说明为什么你需要这样做的令人信服的理由,否则这个问题应该在不清楚的情况下结束。
  • 谢谢!!我是新手,这个帖子非常有帮助。我来自 C++ 背景,还不知道如何进入这个领域。

标签: r


【解决方案1】:

要回答您的问题,您可以使用lapply 来实现。例如,考虑以下内容:

创建一些示例数据:

df <- data.frame(Day = rep(seq.Date(from = as.Date('2010-01-01'), to = as.Date('2010-01-30'), by =1), 5))
df$somevar <- rnorm(nrow(df))
head(df)
         Day      somevar
1 2010-01-01 -0.946059466
2 2010-01-02  0.005897001
3 2010-01-03 -0.297566286
4 2010-01-04 -0.637562495
5 2010-01-05 -0.549800912
6 2010-01-06  0.287709994

现在,请注意 unique 可以为您提供一个包含所有唯一日期的向量:

unique(df$Day)
 [1] "2010-01-01" "2010-01-02" "2010-01-03" "2010-01-04" "2010-01-05" "2010-01-06" "2010-01-07" "2010-01-08" "2010-01-09" "2010-01-10"
[11] "2010-01-11" "2010-01-12" "2010-01-13" "2010-01-14" "2010-01-15" "2010-01-16" "2010-01-17" "2010-01-18" "2010-01-19" "2010-01-20"
[21] "2010-01-21" "2010-01-22" "2010-01-23" "2010-01-24" "2010-01-25" "2010-01-26" "2010-01-27" "2010-01-28" "2010-01-29" "2010-01-30"

您可以将其传递给 lapply 以用于子集:

lapply(unique(df$Day), function(x) df[df[,"Day"]==x,])
[[1]]
           Day    somevar
1   2010-01-01 -0.9460595
31  2010-01-01 -0.3434005
61  2010-01-01 -1.5463641
91  2010-01-01 -0.5192375
121 2010-01-01 -1.1780619

[[2]]
           Day      somevar
2   2010-01-02  0.005897001
32  2010-01-02 -1.346336688
62  2010-01-02 -0.321702391
92  2010-01-02 -0.384277955
122 2010-01-02  0.058906305

... (output omitted)

lapply 的输出是一个包含相应数据帧的列表。

不用说,您可以将其分配给一个名称以捕获列表中的所有数据帧,如mylist &lt;- lapply(...)。但是,如果您想在全局环境中使用它们,您可以首先为每个数据框命名,例如使用 setNames 就像在 setNames(mylist, paste0("df", format(unique(df$Day), format = "%Y%m%d"))) 中一样,然后您可以使用 list2env(mylist) 将每个列表元素推送到全局环境中.

但是,正如 cmets 中所述,这可能不是一个好主意。如果您想对每个日期做一些事情,请考虑使用 dplyr 的 group-by 解决方案:例如,假设您想要按日期获取平均值:

library(dplyr)
df %>% group_by(Day) %>% summarize(mean_var = mean(somevar))
# A tibble: 30 x 2
   Day        mean_var
   <date>        <dbl>
 1 2010-01-01  -0.907 
 2 2010-01-02  -0.398 
 3 2010-01-03   0.213 
 4 2010-01-04  -0.142 
 5 2010-01-05  -0.377 
 6 2010-01-06   0.404 
 7 2010-01-07  -0.634 
 8 2010-01-08   1.00  
 9 2010-01-09   0.378 
10 2010-01-10  -0.0863
# ... with 20 more rows

其中每一行对应于分组平均值。这称为split-apply-combine,值得在谷歌上搜索。它会一次又一次地到来。

仅供参考,在基础 R 中,您可以使用例如by,如

by(df$somevar, df$Day, FUN = mean)

尽管dplyrdata.table 可能对用户更友好。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 2020-12-05
  • 2017-06-05
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多