在多维范围内进行子集的最简单方法是什么?

时间:2013-05-02 03:13:02

标签: r

如果之前有人问过,或者我错过了一些明显的事情,我会事先道歉。

我有两个数据集'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))

但是这在很多方面都很棘手。这样做的重复性较低吗?

2 个答案:

答案 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

我对主要原因的猜测是,重复的子集可以避免在排除行之后测试行是否符合所检查的标准。