R使用apply计算特定时间范围内大型数据框中特定行的某些统计信息

时间:2016-03-18 10:40:28

标签: r for-loop apply

编辑:

我编辑了这个问题以包含更多信息以及为什么我不能只使用简单的sum / mean函数:

我需要在特定时间范围内计算特定行子集的总和,并使用for循环使其工作正常,但是我的数据集很大且for循环效率不高,所以我试图使用apply相反,但无法使其发挥作用。

以下是简单数据集的工作示例。我需要的是计算每个类别的总和,但只计算在过去一小时内具有该值的任何类别,并将其作为新列添加到此数据集。我正在使用unix来简化它并使用数字。

(注意:实际上我想知道在过去一小时内在A站和B站之间的所有列车的平均延误 - 只是为了将其带入上下文中)

#Create basic dataframe: 
category = c("a", "b", "a", "c", "a")
value = c(1:5)
time = c(1444305900,1444306587, 1444305600, 1444291200, 1444291900 )
sum = NA
d = data.frame(category,time,value, sum, stringsAsFactors = FALSE)
This returns:
> d
  category       time value
1        a 1444305900     1
2        b 1444306587     2
3        a 1444305600     3
4        c 1444291200     4
5        a 1444291900     5

请注意,第一个a是晚上12点05分,第二个是晚上12点,第三个是早上8点。因此,当我想获得前一个小时的平均值时,第一个a在前一个小时内没有其他a,而第二个a拥有自己而另一个a提前5分钟,因此需要从第一个和第二个a计算总和。

然后我运行for循环来计算每个类别的总和,并将其添加到先前创建的sum列中:

#Run it as a loop: 
for (i in 1:nrow(d)){
  pickcategory = d[i,c("category")]   #here I select my categroy that I want to filter on
  pickunix = d[i,c("time")]
  filterrows = filter(d, grepl(pickcategory,category)) #here I am subsetting the entire dataframe for only those rows containing this category
  filterhour = filterrows[filterrows$time <= pickunix & filterrows$time > (pickunix-3600),] #subset for previous hour
  getsum = sum(filterhour$value)  #get the mean value for that category
  d$sum[i] = getsum  #add that mean value to that row
}

这提供了我想要的输出:

  category       time value sum
1        a 1444305900     1   4
2        b 1444306587     2   2
3        a 1444305600     3   3
4        c 1444291200     4   4
5        a 1444291900     5   5

但是:这对于1亿行来说很慢,所以我尝试了申请,但是我觉得它不行。围绕应用的所有教程都是非常简单的,人们不使用自定义编写函数,所以我无法弄明白。

pickcategory的第一行中已经出错了,因为它选择了整列,而不是我想要运行该函数的那一行的值。

testfunction= function(d){
  pickcategory = d$category   #here I select my categroy that I want to filter on
  pickunix = d$time
  filterrows = filter(d, grepl(pickcategory,category)) #here I am subsetting the entire dataframe for only those rows containing this category
  filterhour = filterrows[filterrows$time <= pickunix & filterrows$time > (pickunix-3600),] #subset for previous hour
  getsum = sum(filterhour$value)  #get the mean value for that category
  d$sum = getsum #add that mean value to that row
  return(d)
  }

output = apply(d, 1, function(x) testfunction(d))

有人能告诉我如何将循环变成高效的应用函数吗?

请注意,我的实际示例并未计算总和,而是更复杂的内容,因此这需要适用于我想要进行的任何类型的计算和类别选择。

任何帮助都会非常感激。

0 个答案:

没有答案