如果之前有人问过,或者我错过了一些明显的事情,我会事先道歉。
我有两个数据集'olddata'和'newdata'
set.seed(0)
olddata <- data.frame(x = rnorm(10, 0,5), y = runif(10, 0, 5), z = runif(10,-10,10))
newdata <- data.frame(x = -5:5, z = -5:5)
我从旧数据创建模型,并希望预测新数据中的值
mymodel <- lm(y ~ x+z, data = olddata)
predict.lm(mymodel, newdata)
但是,我想将'newdata'中的变量范围限制在训练模型的变量范围内。
当然我可以这样做:
newnewdata <- subset(newdata,
x < max(olddata$x) & x > min(olddata$x) &
z < max(olddata$z) & z > max(olddata$z))
但是这在很多方面都很棘手。这样做的重复性较低吗?
答案 0 :(得分:3)
似乎newdata
中的所有值都已经在适当的范围内,因此没有任何内容可以用于子集。如果我们扩展newdata
的范围:
set.seed(0)
olddata <- data.frame(x = rnorm(10, 0,5), y = runif(10, 0, 5), z = runif(10,-10,10))
newdata <- data.frame(x = -10:10, z = -10:10)
newdata
x z
1 -10 -10
2 -9 -9
3 -8 -8
4 -7 -7
5 -6 -6
6 -5 -5
7 -4 -4
8 -3 -3
9 -2 -2
10 -1 -1
11 0 0
12 1 1
13 2 2
14 3 3
15 4 4
16 5 5
17 6 6
18 7 7
19 8 8
20 9 9
21 10 10
然后,我们需要做的就是确定olddata
的每个变量的范围,然后循环遍历subset
的{{1}}次迭代,其中newdata
包含列:
ranges <- sapply(olddata, range, na.rm = TRUE)
for(i in 1:ncol(newdata)) {
col_name <- colnames(newdata)[i]
newdata <- subset(newdata,
newdata[,col_name] >= ranges[1, col_name] &
newdata[,col_name] <= ranges[2, col_name])
}
newdata
x z
4 -7 -7
5 -6 -6
6 -5 -5
7 -4 -4
8 -3 -3
9 -2 -2
10 -1 -1
11 0 0
12 1 1
13 2 2
14 3 3
15 4 4
16 5 5
17 6 6
答案 1 :(得分:2)
以下是使用* apply系列的方法(使用SchaunW的新数据):
set.seed(0)
olddata <- data.frame(x = rnorm(10, 0, 5), y = runif(10, 0, 5), z = runif(10,-10,10))
newdata <- data.frame(x = -10:10, z = -10:10)
minmax <- sapply(olddata[-2], range)
newdata[apply(newdata, 1, function(a) all(a > minmax[1,] & a < minmax[2,])), ]
需要注意,因为我假设olddata
的列(在删除第二列之后)与newdata
相同。
简洁是以速度为代价的。将nrow(newdata)
增加到2000以强调差异后我发现:
test replications elapsed relative user.self sys.self user.child sys.child
1 orizon() 100 2.193 27.759 2.191 0.002 0 0
2 SchaunW() 100 0.079 1.000 0.075 0.004 0 0
我对主要原因的猜测是,重复的子集可以避免在排除行之后测试行是否符合所检查的标准。