1

这是R 的另一个版本 - 如何在另一列上的条件定义的间隔之间对列中的对象求和

我有 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
}
4

3 回答 3

3

除非我误解了你的目标,否则不需要所有的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 
于 2013-09-23T14:24:39.167 回答
2

k并且j在您的循环中是相同的,并且内部循环可以替换为矢量化版本:

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. 可以在等于orfindInterval时做意想不到的事情,因此您可以改为使用明确说明不等式。t3t1[i]t2[i]which(t3 > t1[i] & t3 < t2[i])

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

于 2013-09-23T16:03:53.117 回答
1

您必须重置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
}
于 2013-09-23T14:14:07.920 回答