【问题标题】:locate dates of evenly-spaced events定位均匀间隔事件的日期
【发布时间】:2020-07-25 03:16:48
【问题描述】:

我希望在给定事件数量和感兴趣期间的天数时找到均匀间隔事件的日期。这似乎是一个微不足道的目标,但它让我感到困惑。

这是一个非常简单的示例,它有一个直接的解决方案:

n.trips <-  5
n.days  <- 20

mean.trips.per.day <- n.trips / n.days

cummulative.trips <- mean.trips.per.day * c(1:n.days)
cummulative.trips
#[1] 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00
#    2.25 2.50 2.75 3.00 3.25 3.50 3.75 4.00 4.25 4.50 4.75 5.00

# Find the date of each trip
which(cummulative.trips %in% c(1:n.days))
#[1]  4  8 12 16 20

但是下面的例子不是直截了当的。显示了三种可能的解决方案,但没有一个与所需结果匹配。在这个例子中,我试图找出向量cummulative.trips 中与整数1:6 最接近的六个元素的位置。这些位置显示在矢量desired.dates

n.trips <-  6
n.days  <- 17

# Here are the desired results
date.of.first.trip   <-  3  # 1.0588235
date.of.second.trip  <-  6  # 2.1176471
date.of.third.trip   <-  8  # or 9: 2.8235294 3.1764706; 8 is the first 
date.of.fourth.trip  <- 11  # 3.8823529
date.of.fifth.trip   <- 14  # 4.9411765
date.of.sixth.trip   <- 17  # 6.0000000
desired.dates <- c(3,6,8,11,14,17)

mean.trips.per.day <- n.trips / n.days

cummulative.trips <- mean.trips.per.day * c(1:n.days)
cummulative.trips
#[1] 0.3529412 0.7058824 1.0588235 1.4117647 1.7647059
#    2.1176471 2.4705882 2.8235294 3.1764706 3.5294118
#    3.8823529 4.2352941 4.5882353 4.9411765 5.2941176 5.6470588 6.0000000

我尝试了以下三种可能的解决方案:

# Find the date of each trip
which(cummulative.trips %in% c(1:n.days))
#[1] 17

which(round(cummulative.trips) %in% c(1:n.days))
#[1]  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17

round(seq(1, n.days, length = n.trips))
#[1]  1  4  7 11 14 17

编辑

我尝试了 MrFlick 在评论中建议的这个函数,但它返回的结果与我在上面为我的第二个示例尝试的三种方法中的第一种方法的结果基本匹配。

What is the fastest way to check if a number is a positive natural number? (in R)

is.naturalnumber <-
function(x, tol = .Machine$double.eps^0.5)  x > tol & abs(x - round(x)) < tol

x <- cummulative.trips
is.naturalnumber(x)
#[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

【问题讨论】:

  • 所以你基本上只是想在列表中找到整数值?这得到 very tricky with floating point numbers 。也许使用this function to check for integers。但请记住,在涉及小数时检查确切的值时要小心。计算机的计算方式与人类不同。
  • @MrFlick 我尝试了我认为您建议的功能,但它似乎不起作用。我将它添加到我原来的帖子的底部。
  • @MrFlick 为了澄清,在我的第二个示例中,我试图挑选出向量cummulative.trips 的六个元素的位置,它们与整数 1:6 最接近。这些位置显示在矢量desired.dates 中。
  • 好的。这与它看起来的样子不同。看起来您正在尝试查找完全匹配,而不是最接近的匹配。

标签: r sequence


【解决方案1】:

也许这样的事情会起作用

nearest_index <- function(targets, values) {
    sapply(targets, function(x) which.min(abs(values-x)))
}
nearest_index(1:6, cummulative.trips)
# [1]  3  6  8 11 14 17

对于每个“目标”值,我们找到最小化观察值之间差异的值。

【讨论】:

  • 谢谢。这很可能会奏效。我想看看它有多普遍。我怀疑我需要一些类似于找到最小值或最大值的算法的东西,这似乎就是你的功能。
【解决方案2】:

在使用n.tripsn.days 的多种组合检查@MrFlick 的答案后,我发现他的代码没有返回我预期的答案(n.trips &lt;- 26; n.days &lt;- 13)。假设我正确使用了他的代码:

[1]  1  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13

但我期待:

[1]  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13

我可能应该在我的原始帖子中更清楚地解释我的问题。我最终编写了以下for-loop,并使用下面列出的n.tripsn.days 的10 种组合对其进行了测试。到目前为止,for-loop 似乎返回了我对所有 10 种组合的期望。这段代码确实包含了@MrFlick 的方法,尽管形式上做了很大的修改。

mean.trips.per.day <- n.trips / n.days
mean.trips.per.day

cummulative.trips.by.day <- mean.trips.per.day * c(1:n.days)
cummulative.trips.by.day

date.of.trip <- rep(0, n.trips)

for(i in 1:n.trips) {

     trip.candidate.days <- which(round(cummulative.trips.by.day) >= i)

     if(length(trip.candidate.days) >  0) date.of.trip[i] = trip.candidate.days[which.min(abs(cummulative.trips.by.day[trip.candidate.days] - i))]

     # no dates have a value that rounds to >= i which suggests there was at most i-1 trips
     if(length(trip.candidate.days) == 0) date.of.trip[i] = 0

}

cummulative.trips.by.day

date.of.trip

这是我迄今为止用来测试此代码的n.tripsn.days 的 10 种组合。

n.trips <- 12
n.days  <- 12

n.trips <-  6
n.days  <- 12

n.trips <-  5
n.days  <- 13

n.trips <- 26
n.days  <- 13

n.trips <- 28
n.days  <- 13

n.trips <- 20
n.days  <- 13

n.trips <-  0
n.days  <- 13

n.trips <-  1
n.days  <- 13

n.trips <-  2
n.days  <- 13

n.trips <- 100
n.days  <-  23

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-01
    • 2015-10-06
    • 1970-01-01
    • 2013-12-09
    • 2014-08-22
    • 1970-01-01
    • 2022-08-03
    • 2014-07-28
    相关资源
    最近更新 更多