循环遍历大量元素并计算R中的平均值

时间:2015-08-09 13:52:49

标签: r time split average

让我需要的结构基本上做我想要的结构所涉及的程序很长,所以请耐心等待。

我创建了一个大量的每日元素列表,这些元素分为几个星期:

jobs <- sample(1:100, size = 4018, replace = TRUE)
unemployed <- sample(1:100, size = 4018, replace = TRUE)
insurance <- sample(1:100, size = 4018, replace = TRUE)
daily_seq <- seq(as.Date("2004-01-01"), as.Date("2014-12-31"), by = "days")
daily_df <- data.frame(daily_seq, jobs, unemployed, insurance)
library(xts)
daily_xts <- xts(daily_df[-1], order.by = as.Date(daily_seq))
# split daily series into list of daily series split by calendar months:
split_list1 <- split(daily_xts, f = "months", drop = FALSE, k = 1)
# split further into large list of weekly elements with daily data define by week number 1:4:
splitlist1 = NULL
for (i in 1:length(split_list1)) {
intervals <- cut(.indexmday(split_list1[[1]]), c(0, 7, 14, 21, 31), 1:4)
splitlist1[[i]] <- split(split_list1[[i]], intervals)
splitlist1
}

splitlist1是平衡日历周元素的大型列表。

我实际上要做的是循环每个“周”并计算每日系列的每周平均值。

我创建了一系列日期,以对应我想要的输出矩阵对象的周数:

# date sequence corresponding to weekly averaged dates needed. "v2" is the sequence:
library(lubridate)
v1 <- seq(as.Date("2004-01-01"), as.Date("201-12-31"), by = "week")
lst <- split(v1, list(month(v1), year(v1)), drop=TRUE) # split vector into months and years
days <- substr(v1[1:4],9,10) # substring extracts first 4 observations from a month as the basis of the sequence
v2 <- unlist(lapply(lst, function(y) {
sprintf('%s%s', substr(y[1:4], 1,8), days)}), use.names=FALSE)

# create matrix for desired output:
week_matrix = matrix(NA, nrow = length(v2), ncol = ncol(split_list1[[1]]), dimnames = dimnames(split_list1[[1]][1]))

然后我继续用这些代码行计算相应的平均值:

# loop through each weekly element "j" of daily data and calculate weekly average:
for (i in 1:length(splitlist1)) {
for (j in 1:4) {
for (n in 1:ncol(splitlist1[[1]]$`1`)){
 week_matrix[i,n] <- weighted.mean(splitlist1[[i]]$'j'[,n])
 week_matrix
 }}}

但是,它返回与代码行Error in 1:ncol(splitlist1[[1]]$j) : argument of length 0相关的错误,即使在特定周j运行此行也会返回一个整数。 此外,如果我删除这行代码,它会显示一个空矩阵,其中没有计算。

我已经尝试了我能想到的代码行的所有可能变体,但是我无法生成我想要的输出。我想要的输出是一个矩阵/ xts类型的对象,沿着与v2日期序列对应的行的每周平均值,以及与jobs; unemployed; and insurance对应的列

你能帮我解决这个问题吗?!提前谢谢。

3 个答案:

答案 0 :(得分:1)

你所拥有的是dplyr中tapply,by或aggregate like工具的工作。关键是开发你想要迭代的索引。以下是使用tapply的示例。

创建虚拟数据:

jobs <- sample(1:100, size = 4018, replace = TRUE)
unemployed <- sample(1:100, size = 4018, replace = TRUE)
insurance <- sample(1:100, size = 4018, replace = TRUE)
daily_seq <- seq(as.Date("2004-01-01"), as.Date("2014-12-31"), by = "days")
daily_df <- data.frame(daily_seq, jobs, unemployed, insurance)

添加索引以唯一标识每周:

daily_df$week = rep(seq(as.Date("2004-01-01"), as.Date("2014-12-31"),
    by = "week"), each=7)
daily_df$YR.week = paste(strftime(daily_df$daily_seq, "%Y"), daily_df_week)

对按年和周分组的每个集重复您的平均值:

tapply(daily_df$jobs, daily_df$YR.week, mean)

答案 1 :(得分:1)

与@MikeRSpencer描述的理念相同。 我使用了lubridate和dplyr包:

library(dplyr)
library(lubridate)

jobs <- sample(1:100, size = 4018, replace = TRUE)
unemployed <- sample(1:100, size = 4018, replace = TRUE)
insurance <- sample(1:100, size = 4018, replace = TRUE)
daily_seq <- seq(as.Date("2004-01-01"), as.Date("2014-12-31"), by = "days")
daily_df <- data.frame(daily_seq, jobs, unemployed, insurance)


daily_df %>%
  mutate(WeekOfYear = week(daily_seq)) %>% # obtain week of year
  group_by(WeekOfYear) %>% # group by that 
  select(-daily_seq) %>% # remove variables you don't need to average on
  summarise_each(funs(mean))

请注意,作为变量&#34;一年中的一周&#34;如果您在数据集中包含多年,则可以重复使用&#34;一年中的一周&#34;和&#34;年&#34;为你的分组。

答案 2 :(得分:1)

  

我实际上要做的是循环每个“周”并计算每日系列的&gt;每周平均值。

如果我理解正确的话,你想用“月周”号1开始每个月初。 让我们从计算正确的“月周”数字开始:

daily_xts$mo <- strftime(index(daily_xts), "%m")
daily_xts$yr <- strftime(index(daily_xts), "%Y")
monthweek <- aggregate( jobs ~ mw + mo + yr , daily_xts, FUN = mean)

请记住,一个月可以在6个日历周内展开,因此我们可以将“月周”数字设为1至6月。2014年11月就是一个例子。

按月“月周”获得平均值i。即对于'工作':

monthweek$date <- as.POSIXct(paste(monthweek$yr, monthweek$mo, "01", sep = "-")) 
monthweek <- monthweek[,c(5,4)]

最后两行用于“化妆品”并添加日期列,并从结果数据框中删除现在“不必要的”'mo'和'yr'列。

SELECT T.custno,T.custlastname,AVG(T.OrderAmount) , T.OrderCount
FROM(
      SELECT  A.custno,A.custlastname,count(b.ordno) as OrderCount,    sum(c.qty*d.prodprice) AS  OrderAmount
  FROM customer A 
      JOIN ordertbl B ON A.custno=b.custno
      JOIN ordline C ON b.ordno=c.ordno
      JOIN  product D ON c.prodno=d.prodno
  WHERE A.custstate='CO'
  GROUP BY A.custno,A.custlastname, b.ordno) AS T
GROUP BY T.custno,T.custlastname;

如果您不想使用“正确”的周数,您可以将第4周和第5周聚合成一个组。我把它留作练习:-)