【问题标题】:Average columns in reverse, and return sum of those averages in R反向平均列,并返回 R 中这些平均值的总和
【发布时间】:2016-10-04 19:17:47
【问题描述】:

我刚刚开始学习 R 用于预测和分析目的,我决定尝试为我正在使用的预测模型创建一个完整的包(Additive Pickup)。我在一家酒店工作,我经常做的事情之一就是预测我们的需求,所以这肯定会让我的这部分工作更快更容易!

我已经创建了一些函数,这些函数将为我获取我的取件号码的数据框,现在我正在开发一个函数来平均该新数据框中用户定义的列数。我已经包含了用于创建一些示例数据的代码,以及我正在处理的代码。

样本数据:

test = data.frame(replicate(10, sample(0:2, 32, rep = TRUE)))

破码:

averagePickup = function(data, day, periods) {
  # data will be your Pickup Data
  # day is the day you're forecasting for (think row number)
  # periods is the period or range of periods that you need to average (a column or range of columns).
 pStart = ncol(data)
 pEnd = ncol(data) - periods
 row = (day-1)
 new_frame = as.data.frame(matrix(nrow = 1, ncol = periods))

 for(i in pStart:pEnd) {
    new_frame[1,i] = mean(data[1:row , i])
  }
 return(sum(new_frame[1,1:i]))
}

这样做的目的是从数据中的最后一列向后迭代到用户定义的时间段。例如,将“周期”设置为 1 应该只返回最后一列的平均值之和。将其设置为 2 将产生最后一列和倒数第二列的平均值之和。

但是,当我尝试对此进行测试时,我收到一个错误,显示为

[(tmp`, 1, i, value = 0.9) 中的错误:新列 会在现有列之后留下孔

如果你们能提供任何建议,我们将不胜感激。另外,让我知道我是否完全零意义,并为关于这个问题的文章道歉......请注意,由于输入数据的格式化方式,这必须向后迭代。

【问题讨论】:

  • 请包含数据以使其可重现
  • 是的...这可能会有所帮助...您可以使用此代码来获得与我正在使用的框架相似的框架。 test = data.frame(replicate(10, sample(0:2, 32, rep = TRUE))) 应用于我的代码,我想从 X10 列开始。让我知道是否还有其他可以使这一点更清楚的事情!
  • Day 是行号,periods 是列号。基本上,每一行是一周中的一天,每一列是一个观察期。如果将 day 设置为 11 并将 periods 设置为 1,则该函数应取第 1 列中前 10 个观察值的平均值。从右到左似乎无法正常工作。

标签: r function


【解决方案1】:

我想这就是你想要的:

averagePickup = function(data, day, periods) {
  # data will be your Pickup Data
  # day is the day you're forecasting for (think row number)
  # periods is the period or range of periods that you need to average (a column or range of columns).
  pStart = ncol(data)
  pEnd = ncol(data) - (periods-1)
  row = (day-1)
  new_frame <- as.data.frame(matrix(nrow = 1, ncol = periods))

  for(i in pStart:pEnd) {
    new_frame[1,1+abs(ncol(data)-i)] <- mean(data[1:row , i])
  }
  return(sum(new_frame[1,1:ncol(new_frame)]))
}

averagePickup(test,1,5)

[1] 7

【讨论】:

  • 是的,这太完美了!
  • 现在因为我是一个完全的菜鸟和学习者,我想确保我理解你所做的改变。您将pEnd 更改为包含(periods-1),我猜当periods 为1 时,pEnd 的值与pStart 相同。我看到的唯一其他更改是您添加@987654327 的位置@。我猜这会将手段以相反的顺序放入新框架中?再次感谢您的所有帮助!
  • @VincentLevinger 不客气。正确的;第一个更改是将索引更正 1 个位置,第二个更改是说“将第一个平均值放在 new_frame 的第一列中,然后为每个额外的平均值增加 1 列”。
  • 感谢您的解释。但是,我不明白第二行如何为每次迭代添加一个新列。如果我们要使用我提供的测试数据(33 行,10 列),那么在第一次迭代中,数学看起来会像下面这样。 new_frame[1, 1 + (10 - 1)]。据我所知,这会将第一个平均值放在第 10 列,然后将第二个平均值放在第 9 列,依此类推。我只是误解了你的描述吗?
  • @VincentLevinger 列索引为1+abs(ncol(data)-i)。第一次迭代是pStart:pEnd,即i = 10。列数ncol(data) 为10。因此列索引为1 + abs(10 - 10),即1 + 0,因此为1。记住pStart 已定义如ncol(data),即10。在您的评论中,您写道它是1。您可能对for 循环的工作方式感到困惑——您正在做for(i in pStart:pEnd),所以第一个i 是10。它不是@987654339 @,所以i 不是从 1 开始的。
【解决方案2】:

我相信这可以满足您的需求:

colMeans 将返回每列的平均值

colMeans(test)
     X1      X2      X3      X4      X5      X6      X7      X8      X9     X10 
1.15625 1.00000 0.90625 1.03125 1.15625 1.09375 0.81250 0.93750 1.15625 0.84375 

现在,您只需要最后的x 列,而不是每一列。 dim 将为您提供矩阵/数据框的尺寸,第二个值是列数。

dim(test)[2]

您现在可以动态地对数据框进行子集化

test[, (dim(test)[2] - x):dim(test)[2]]

最后,将子集数据框插入colMeans 函数,并在其周围包裹sum。

sum(colMeans(test[, (dim(test)[2] - x):dim(test)[2]]))

【讨论】:

  • 这很接近,但不幸的是它没有考虑到我不一定想要整个列的平均值这一事实。另一个答案允许它在选择我想要一起表示的值时更加动态,这是避免在平均值中包含“未来”观察值所必需的。如果我误解了你的代码,请告诉我,我对这一切还是很陌生!
  • 如果您需要按行 1 到 Y 对 df 进行子集化,则将这些行添加为子集中的第一个参数。您已经在问题中包含了该语法。在上面的示例中,这将是 sum(colMeans(test[1:row, ...
猜你喜欢
  • 2017-08-10
  • 2017-10-25
  • 2016-08-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
相关资源
最近更新 更多