R 如何有效地检查数字向量是否在数据帧定义的间隔内

R 如何有效地检查数字向量是否在数据帧定义的间隔内,r,for-loop,if-statement,intervals,R,For Loop,If Statement,Intervals,我有以下问题:我有一个向量n1,其中包含某些值(例如,我随机化了代码中的值)。我有一个数据框df.int,其中包含一列区间上限和一列特定值(再次随机,实际上这些值是其他值的模式)。我想检查n1的每个条目在数据帧的哪个间隔内,然后用相应间隔的第二列的值覆盖n1的值 一般来说,我的代码应该可以工作,但是由于n1的间隔很长,我的脚本运行得太长。所以我想问我如何调整我的代码,使其更有效地工作 代码如下: set.seed(123) seq.vec <- c(seq(400,800000,by=20

我有以下问题:我有一个向量
n1
,其中包含某些值(例如,我随机化了代码中的值)。我有一个数据框
df.int
,其中包含一列区间上限和一列特定值(再次随机,实际上这些值是其他值的模式)。我想检查
n1
的每个条目在数据帧的哪个间隔内,然后用相应间隔的第二列的值覆盖
n1
的值

一般来说,我的代码应该可以工作,但是由于
n1
的间隔很长,我的脚本运行得太长。所以我想问我如何调整我的代码,使其更有效地工作

代码如下:

set.seed(123)
seq.vec <- c(seq(400,800000,by=200))
n1 <- sample(100:800000, 2000, replace=TRUE)
df.int <- data.frame(matrix( nrow=length(seq.vec), ncol=2))
df.names <- c("Upper.Limit", "Value")
colnames(df.int) <- df.names
df.int$Upper.Limit <- seq.vec
df.int$Value <- sample(100:800000, length(seq.vec), replace=TRUE)
j <- 1
m <- 1
for (k in seq_len(n1)){
  for (i in seq_len(df.int$Upper.Limit)){
    if (j==1) {
      n1[m] <- ifelse(n1<=df.int$Upper.Limit[j],df.int$Value[j],n1[m])
    } else{
      n1[m] <- ifelse(n1<=df.int$Upper.Limit[j] & n1>df.int$Upper.Limit[j-1]
                            ,df.int$Value[j],n1[m])
    }
    j <- j+1
  }
  m <- m+1
}
set.seed(123)

seq.vec您可以将
approx
method=“constant”
一起使用,并通过设置
f
参数指定要使用的限制:

## dummy data
n1 <- runif(10, 0, 100)
df.int <- data.frame(
   upper = seq(1, 100, by = 1), 
   value = runif(100, 0, 100)
)


approx(x = df.int$upper, 
       y = df.int$value, 
       xout = n1, 
       method = "constant",  
       f = 1,                
       rule = 2             ## extrapolation behavior outside domain
)
##虚拟数据

n1您可以使用
approx
method=“constant”
并通过设置
f
参数指定要使用的限制:

## dummy data
n1 <- runif(10, 0, 100)
df.int <- data.frame(
   upper = seq(1, 100, by = 1), 
   value = runif(100, 0, 100)
)


approx(x = df.int$upper, 
       y = df.int$value, 
       xout = n1, 
       method = "constant",  
       f = 1,                
       rule = 2             ## extrapolation behavior outside domain
)
##虚拟数据

n1函数
findInterval
性能良好,可以完成任务。
首先了解它如何仅与
n1的第一个元素一起工作

i <- findInterval(n1[1], c(df.int$Upper.Limit, Inf))
j <- findInterval(n1[1], c(-Inf, df.int$Upper.Limit))

df.int$Upper.Limit[i]
#[1] 189000
n1[1]
#[1] 189041
df.int$Upper.Limit[j]
#[1] 189200

df.int$Upper.Limit[i] < n1[1] & n1[1] <= df.int$Upper.Limit[j]
#[1] TRUE

i函数
findInterval
具有良好的性能,可以完成任务。
首先了解它如何仅与
n1的第一个元素一起工作

i <- findInterval(n1[1], c(df.int$Upper.Limit, Inf))
j <- findInterval(n1[1], c(-Inf, df.int$Upper.Limit))

df.int$Upper.Limit[i]
#[1] 189000
n1[1]
#[1] 189041
df.int$Upper.Limit[j]
#[1] 189200

df.int$Upper.Limit[i] < n1[1] & n1[1] <= df.int$Upper.Limit[j]
#[1] TRUE

i如果我理解正确,OP正在寻找一种有效的方法,从给定上限的匹配右闭合区间中选取一个值

对于大型数据集,滚动联接可能值得一看:

library(data.table)
setDT(df.int)[data.table(n1), on = .(Upper.Limit = n1), roll = -Inf]$Value
或者,根据OP的需要更换
n1

n1 <- setDT(df.int)[data.table(n1), on = .(Upper.Limit = n1), roll = -Inf]$Value

请注意对数时间刻度

对于较小的问题规模,
findInterval()
或包装
findInterval()
的函数似乎是最快的方法,而对于增加问题规模,滚动连接则是最快的方法


对于较大的问题大小,内存分配(见表)可能会成为一个问题,这也可能会影响性能。

如果我理解正确,OP正在寻找一种有效的方法,从给定上限的匹配右闭区间中选择一个值

对于大型数据集,滚动联接可能值得一看:

library(data.table)
setDT(df.int)[data.table(n1), on = .(Upper.Limit = n1), roll = -Inf]$Value
或者,根据OP的需要更换
n1

n1 <- setDT(df.int)[data.table(n1), on = .(Upper.Limit = n1), roll = -Inf]$Value

请注意对数时间刻度

对于较小的问题规模,
findInterval()
或包装
findInterval()
的函数似乎是最快的方法,而对于增加问题规模,滚动连接则是最快的方法


对于较大的问题,内存分配(见表)可能会成为一个问题,这也可能会影响性能。

可以从
findInterval(n1,df.int$Upper.Limit)开始
。通过使用相应间隔的第二列的值覆盖
n1
的值,您是指列
值的值吗?区间的哪一个极限,下限还是上限?是的,我想用
value
列的相应值覆盖
n1
。通常,区间定义为
上限[i-1]findInterval(n1,df.int$Upper.Limit)
开始。通过用相应间隔的第二列的值覆盖
n1
的值,您是指列
的值吗?区间的哪一个极限,下限还是上限?是的,我想用
value
列的相应值覆盖
n1
。通常,区间定义为
上限[i-1]DF[[colValues]][i+1]
,因为它使用的是之前间隔的
值。谢谢,非常有效,速度非常快。只需将其调整为
DF[[colValues]][i+1]
,否则它将使用之前间隔的
值。
library(ggplot2)
autoplot(bm)