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)