2013-05-02 74 views
3

如果之前已经询问过,或者我错过了某些明显的事情,我很抱歉。在多维范围内子集的最简单方法?

我有两个数据集,“旧数据”和“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)) 

但是,这在许多方面变得棘手。有没有一个重复的方式来做到这一点?

回答

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 

那么我们需要做的是确定通过的subsetnewdata许多迭代olddata每个变量,然后循环范围有列:

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 
2

下面是使用*申请家庭(使用SchaunW的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) 

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 

我当时的主要原因猜测是重复的子集避免测试行是否符合他们被排除后,检查的标准。

+0

我不知道这是一个矢量化的方法。 'apply'是一个for循环,但是你的实现循环遍历数据的每一行,而不是遍及每一列。我想这就是速度差异来自哪里。 – SchaunW 2013-05-02 14:54:15

+0

已注意。我编辑了我的答案。我还探讨了遍历行是否是性能差异的原因。在列上使用mapply仅为迭代子集的2.6倍。 – orizon 2013-05-03 00:37:54