R + Lookup算法匹配一系列相同元素中的值

时间:2014-02-01 21:53:57

标签: r algorithm

我正在寻找一种在数据框架上使用查找算法的方法,对于给定的元素,该算法检查范围内的相应变量并返回最大这样的变量。一般的要点是我希望函数能够(1)查看给定的元素,(2)找到同名的所有其他元素,(3)在同名的所有元素中,查看相应的变量是否在+内 - X 的任何其他人,以及(4)如果是,则返回其中的最大值;如果没有,只需返回该变量。

一个具体的例子是一些时间戳数据。假设我订购了按日期,小时和分钟分类的2家企业。我想查看每日订单,但问题是如果订单在2分钟之内完成,它们会被重复计算,所以我只想在这种情况下查看最大值。

*编辑:我应该说如果订单在几分钟之内连续记录,我们假设它们是重复的,只想要最大值。因此,如果4个订单进来,每隔一分钟一次,但是那时没有其他订单从最后一个+2分钟和-2从第一个开始,我们可以假设4组只应计算一次,它应该是计算的最大值

以下是一些数据:

data <- structure(list(date = structure(c(16090, 16090, 16090, 16090, 
16090, 16090, 16090, 16090, 16090, 16090, 16090, 16090, 16091, 
16091, 16091, 16091, 16091, 16091, 16091), class = "Date"), company = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L), .Label = c("ABCo", "Zyco"), class = "factor"), hour = c(5L, 
5L, 5L, 7L, 7L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 6L, 6L, 6L, 7L, 7L, 
7L, 8L), minute = c(21L, 22L, 50L, 13L, 20L, 34L, 47L, 34L, 35L, 
20L, 44L, 19L, 14L, 16L, 37L, 24L, 26L, 49L, 50L), orders = c(59L, 
46L, 31L, 15L, 86L, 23L, 8L, 71L, 86L, 44L, 23L, 47L, 6L, 53L, 
21L, 54L, 73L, 63L, 4L)), .Names = c("date", "company", "hour", 
"minute", "orders"), row.names = c(NA, -19L), class = "data.frame")

我关心的是,对于每家公司,在给定的日期,在给定的小时内,如果有任何条目相互下降+ - 2分钟,我想取“订单”的最大值。如果给定的条目在+ - 2分钟内没有任何内容,那么只需保留给定的“订单”值。 (在这种情况下,前两行“数据”,ABCo在2014-01-20 at hour = 5,因为第21和22分钟在彼此的+ -2之内,我们将返回最大值订单,所以59.第三行,ABCo在1-20小时= 5和分钟= 50没有其他分钟+ -2,所以我们只保留订单的价值,31 )< / p>

以公司+日期+小时的形式查看分钟和订单数据的起点可以是将这3个术语连接在一起并重新组织数据框:

data$biztime <- do.call(paste, c(data[c("company","date","hour")], sep = "_"))

data2 <- ddply(data, .(biztime, minute), summarise, orders = sum(orders))

但是从这里我迷失了。是否有任何简单的方法可以使用 ifelse 语句在这些数据框中添加另一列,或者在这些行上执行上述某种条件操作的其他内容?

2 个答案:

答案 0 :(得分:4)

添加一列datetime对象:

data <- transform(data,
   datetime = strptime(sprintf("%s %s:%s", date, hour, minute),
                       format = "%Y-%m-%d %H:%M"))

添加一列索引,其中两行之间的两行将共享相同的索引:

data <- ddply(data, .(company), transform, timegroup =
              cumsum(c(TRUE, diff(datetime, units = "mins") > 2)))

最后,总结一下:

ddply(data, .(company, timegroup), summarise,
      orders = max(orders),
      datetime = datetime[1])

#    company timegroup orders            datetime
# 1     ABCo         1     59 2014-01-20 05:21:00
# 2     ABCo         2     31 2014-01-20 05:50:00
# 3     ABCo         3     15 2014-01-20 07:13:00
# 4     ABCo         4     86 2014-01-20 07:20:00
# 5     ABCo         5     53 2014-01-21 06:14:00
# 6     ABCo         6     21 2014-01-21 06:37:00
# 7     ABCo         7     73 2014-01-21 07:24:00
# 8     ABCo         8     63 2014-01-21 07:49:00
# 9     ABCo         9      4 2014-01-21 08:50:00
# 10    Zyco         1     23 2014-01-20 05:34:00
# 11    Zyco         2      8 2014-01-20 05:47:00
# 12    Zyco         3     86 2014-01-20 06:34:00
# 13    Zyco         4     44 2014-01-20 07:20:00
# 14    Zyco         5     23 2014-01-20 07:44:00
# 15    Zyco         6     47 2014-01-20 08:19:00

答案 1 :(得分:0)

除非我误解了某些内容,否则这可能会有所帮助;可能很慢,我想。

data$gr = as.numeric(interaction(data$company, data$date, data$hour))

ff = function(mins, ords) {
 unlist(lapply(mins, function(x) max(ords[abs(x - mins) <= 2])))
}

do.call(rbind, 
             lapply(split(data, data$gr), 
                        function(x) transform(x, new_val = ff(x$minute, x$orders))))

#            date company hour minute orders gr new_val
#1.1   2014-01-20    ABCo    5     21     59  1      59
#1.2   2014-01-20    ABCo    5     22     46  1      59
#1.3   2014-01-20    ABCo    5     50     31  1      31
#2.6   2014-01-20    Zyco    5     34     23  2      23
#2.7   2014-01-20    Zyco    5     47      8  2       8
#6.8   2014-01-20    Zyco    6     34     71  6      86
#6.9   2014-01-20    Zyco    6     35     86  6      86
#7.13  2014-01-21    ABCo    6     14      6  7      53
#7.14  2014-01-21    ABCo    6     16     53  7      53
#7.15  2014-01-21    ABCo    6     37     21  7      21
#9.4   2014-01-20    ABCo    7     13     15  9      15
#9.5   2014-01-20    ABCo    7     20     86  9      86
#10.10 2014-01-20    Zyco    7     20     44 10      44
#10.11 2014-01-20    Zyco    7     44     23 10      23
#11.16 2014-01-21    ABCo    7     24     54 11      73
#11.17 2014-01-21    ABCo    7     26     73 11      73
#11.18 2014-01-21    ABCo    7     49     63 11      63
#14    2014-01-20    Zyco    8     19     47 14      47
#15    2014-01-21    ABCo    8     50      4 15       4