【问题标题】:How to sum the variables according to the times it falls into t1[i] < t[j] < t2[i]如何根据它落入 t1[i] < t[j] < t2[i] 的时间对变量求和
【发布时间】:2013-09-24 00:03:53
【问题描述】:

这是R - How to sum objects in a column between an interval defined by conditions on another column的另一个版本

我有 3 个时间变量 t1、t2 和 t3 以及一个带有数字的相应列。我想将“数字”中的变量汇总在一起,这些变量将落在t1[i]t2[i] 之间的时间范围内。例如:

t1 <- c(1.12, 2.16, 3.18, 4.56, 8.90, 29.36, 30.30, 31.30, 36.90, 50.01)
t2 <- c(2.14, 2.77, 3.65, 4.78, 8.99, 30.01, 31.07, 31.89, 40.30, 55.08)
t3 <- c(1.16, 1.55, 1.35, 2.17, 2.18, 2.19, 2.34, 3.30, 4.59, 8.91, 29.99, 30.32, 30.98, 31.32, 37.00, 52.00, 54.00)
numbers <- c(7,1,2,5,5,6,9,12, 13, 22, 7, 1, 7, 11, 21, 29)

输出我正在寻找如下输出:这里我有 t3 中的前 3 个数字满足我的标准,依此类推,它们被汇总并存储在一个新的向量“输出”中。请注意,这里的“输出”是我自己编写的,不是计算出来的(如示例所示)。我可以计算第一组,但是我的 i 保持在相同的值,我不能继续......希望你能帮助我,谢谢你的时间。

output = (7+1+2,5+5+6+9,12,13,22,7,1,7,11,21+29) 
output = (10, 25, 12, 13, 22, 7, 1, 7, 11, 50)

到目前为止,这是我所拥有的:

t1 <- c(1.12, 2.16, 3.18, 4.56, 8.90, 29.36, 30.30, 31.30, 36.90, 50.01)
t2 <- c(2.14, 2.77, 3.65, 4.78, 8.99, 30.01, 31.07, 31.89, 40.30, 55.08)

t3 <- c(1.16, 1.55, 1.35, 2.17, 2.18, 2.19, 2.34, 3.30, 4.59, 8.91, 29.99, 30.32, 30.98, 31.32, 37.00, 52.00, 54.00)
numbers <- c(7,1,2,5,5,6,9,12, 13, 22, 7, 1, 7, 11, 21, 29)

i = 1
j = 1
k = 1
N = NULL
Sums = NULL

while (j < length(t1))
{
  while (i < length(t3))
    {
      if (t3[i] > t1[j] & t3[i] <= t2[j])
      {
        N[i] <- numbers[i]

      }
      i = i + 1
    } 
  Sums[k] = sum(N)   
  k = k + 1
  j = j + 1
}

【问题讨论】:

  • 不应该t3numbers 有相同数量的元素?它们分别有 17 和 16 个元素。
  • 是的,你说得对,它们应该是相同的长度。我只是在画一个例子。它们很长 1000+

标签: r


【解决方案1】:

除非我误解了您的目标,否则不需要所有 whiles 和 ifs。

首先,整理你的数据,即:

dat <- data.frame(time=t3[1:16], obs=numbers)

然后使用cut 将数据切割成区间,并与tapply 相加,类似于:

all <- tapply(dat$obs, cut(dat$time, breaks=sort(c(t1, t2))), FUN=sum)
# omit the gaps between intervals
all[seq(1,length(all),by=2)]
(1.12,2.14] (2.16,2.77] (3.18,3.65] (4.56,4.78]  (8.9,8.99]   (29.4,30] (30.3,31.1] (31.3,31.9] (36.9,40.3]   (50,55.1] 
     10          25          12          13          22           7           8          11          21          29 

【讨论】:

  • 感谢您的帮助 blmoore,非常感谢。求和的方式是将所有属于 t1 和 t2 之间的数字相加,不幸的是它们不是恒定的并且一直在变化。然而,t3 总是在 t1[i] 和 t2[i] 之间。为了清楚起见,t1 和 t2 是相同的向量,它们分别是 t1[i] 和 t1[i+1],我只是这样指定它,这样我就可以存储我之前操作的最后一个数字。在 t1 和 t2 之间可能有大量数字(最多 100 个)。我必须把它们全部总结起来:(。
  • 啊,在这种情况下,您只需要在调用cut 时使用breaks=t1all 将保存您的所有结果(不需要跳过索引)
  • 我的时间间隔为纳秒,它们不是唯一的,我试图操纵它。而且我确实理解您将如何去做,但是它似乎不起作用“'休息'并不是唯一的”。我特别需要设置一个带中断的范围
  • 它们不是唯一的中断吗?在大多数应用程序中,除非您想重复计算观察结果,否则它们可能应该是?
  • 非常感谢您提供的所有帮助以及您富有洞察力的意见,这真的很有帮助。我更习惯于 C++ 结构,因此我尝试以这种方式编程,并以这种方式构建问题。你很好,再次感谢你!!!
【解决方案2】:

kj 在你的循环中是相同的,内部循环可以替换为矢量化版本:

t3 <- head(t3,-1) # editing the error the OP left in place
nint <- length(t1)
N <- vector('list',nint)
Sums <- vector('integer',nint)
for (i in 1:nint){
    N[[i]] <- numbers[which(findInterval(t3,c(t1[i],t2[i]))==1)]
    Sums[i] <- sum(N[[i]])
}

评论 1。 这给出了与@bmoore 相同的结果,数字存储在 N 中,然后在 Sums 中求和。我认为,您需要 N 成为一个列表来做您想做的事情,而这一行

N[i] <- numbers[i]

正在覆盖单个值,而不是像 @holgrich 对 c(N,numbers[i]) 所做的那样将其添加到向量中。

评论 2。t3 等于t1[i]t2[i] 时,findInterval 会做出意想不到的事情,因此您可以改用which(t3 &gt; t1[i] &amp; t3 &lt; t2[i]) 来明确说明不等式。 p>

评论 3. 完全不使用循环,就像@bmoore 的回答一样,是 R 中更标准的做法。

【讨论】:

  • 感谢弗兰克的帮助,非常感谢!我正在解码每一行,试图理解你为什么要这样!万事如意!
【解决方案3】:

您必须在运行循环时重置 iN

t1 <- c(1.12, 2.16, 3.18, 4.56, 8.90, 29.36, 30.30, 31.30, 36.90, 50.01)
t2 <- c(2.14, 2.77, 3.65, 4.78, 8.99, 30.01, 31.07, 31.89, 40.30, 55.08)

t3 <- c(1.16, 1.55, 1.35, 2.17, 2.18, 2.19, 2.34, 3.30, 4.59, 8.91, 29.99, 30.32, 30.98, 31.32, 37.00, 52.00, 54.00)
numbers <- c(7,1,2,5,5,6,9,12, 13, 22, 7, 1, 7, 11, 21, 29)

i = 1
j = 1
k = 1
N = c()
Sums = NULL

while (j < length(t1)){
  while (i < length(t3)){
      if (t3[i] > t1[j] & t3[i] <= t2[j]) N <- c( N, numbers[i] )
      i = i + 1
  }
  i = 1 
  Sums[k] = sum(N)   
  N = c()
  k = k + 1
  j = j + 1
}

【讨论】:

  • 忘了感谢您的解决方案,它非常有用。我真的很感激有像你这样的人存在并且乐于提供帮助!
猜你喜欢
  • 1970-01-01
  • 2019-04-19
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多