我正在寻找一种在数据框架上使用查找算法的方法,对于给定的元素,该算法检查范围内的相应变量并返回最大这样的变量。一般的要点是我希望函数能够(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 语句在这些数据框中添加另一列,或者在这些行上执行上述某种条件操作的其他内容?
答案 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