2015-03-31 56 views
1

我正在做一些使用subset()的子集,但在我的逻辑语句中使用%in%命令时遇到了一些问题。R中使用%进行子集数据的条件使用%

考虑像

x11 x21 x12 x22 
1 19 2000 32 2004 
2 19 2000 20 2001 

一个简单的数据结构我想的一个子集,其中这是事实,x12要么等于x22-x21+x11或等于x22-x21+x11+1。*对于上面的例子,我想在第二行中,由于当且仅当x12是20或21时,该逻辑陈述应评估为TRUE。对于这个简单的设置,对我下面的作品:

> test1 <- data.frame(x11=c(19, 19), x21=c(2000, 2000), x12=c(32, 20), x22=c(2004, 2001)) 
> subset(test1, (x12 %in% c(x22-x21+x11, x22-x21+x11+1))) 
    x11 x21 x12 x22 
2 19 2000 20 2001 

,当我介绍其他行,就会出现问题。添加一行:

x11 x21 x12 x22 
1 19 2000 32 2004 
2 19 2000 20 2001 
3 30 1998 32 2000 

现在,我想子集这个,以便我得到第二和第三行。但是使用与上面相同的子集策略:

> test2 <- data.frame(x11=c(19, 19, 30), x21=c(2000, 2000, 1998), x12=c(32, 20, 32), x22=c(2004, 2001, 2000)) 
> subset(test2, (x12 %in% c(x22-x21+x11, x22-x21+x11+1))) 
    x11 x21 x12 x22 
1 19 2000 32 2004 
2 19 2000 20 2001 
3 30 1998 32 2000 

所以现在我得到了第一个例子中没有得到的行。我的猜测是它与允许x12的矢量相关,即c(x22-x21+x11, x22-x21+x11+1),但我不确定如何构建这个,以便暗示它是“按行”而不是所有行的一个矢量。

想法非常感谢!


* X11是个体在时间点X21年龄,和X 12是一个(可能不同的)个体的在时间点X22的年龄。我想要包含x21的年龄(x11)与x22的年龄(x12)在逻辑和物理上兼容的行的子集;在2000年,19岁的个人在2001年是19,20或21岁,这取决于生日(但是由于其他原因,我放弃了这个年龄相同的年龄的可能性)。因此,我们在2000年有19岁,在2004年有32岁的第一行对同一个人来说是不可能的。

+0

'如果年龄差是possible' - 你的意思是检查是否'x12'是*之间*'X22-X21 + x11'和'X22-X21 + X11 + 1'? – zx8754 2015-03-31 11:56:20

+0

@ zx8754看起来我把这个句子的某些部分放在那里,我编辑了我的文章,使它更有意义(我希望)。 – hejseb 2015-03-31 12:00:37

回答

2

首先,要小心浮点精度限制。如果你的值都是整数,这没有关系,但在一般情况下,x==y可能会失败,除非你使用像all.equal这样的工具。现在
,而不是subset%in%碴,只写一个条件:

foo <- test1[(test1[,3]==(test1[,1]-test1[,2]+test1[,4])) | 
       (test1[,3]==(test1[,1]-test1[,2]+test1[,4]+1)), ] 

您可能需要在一行一行地规则运行apply

+0

这似乎做得很好,但是如果建议将这种方法用于大型矩阵,您是否知道(离开您的头顶)?或者有这样的用途,我应该以某种方式改变它吗? – hejseb 2015-03-31 12:08:04

+0

我怀疑使用'< - ['运算符是更快的方法。你可能想要做一些时间试验。 – 2015-03-31 13:58:34

+0

我在我的代码中使用了这个,但是在答案中有一些错误(缺少括号和加号而不是减号)。为了将来的参考,它应该读取'foo < - test1 [(test1 [,3] ==(test1 [,1] -test1 [,2] + test1 [,4]))| (test1 [,3] ==(test1 [,1] -test1 [,2] + test1 [,4] +1)),]'。 – hejseb 2015-04-01 05:46:37

1

试试这个:

#data 
test2 <- data.frame(x11=c(19, 19, 30), 
        x21=c(2000, 2000, 1998), 
        x12=c(32, 20, 32), 
        x22=c(2004, 2001, 2000)) 
#range pre-computed 
test2$in1 <- test2$x22-test2$x21+test2$x11 
test2$in2 <- test2$x22-test2$x21+test2$x11+1 

#subset 
test2[ test2$x12 >= test2$in1 & 
     test2$x12 <= test2$in2,] 
# x11 x21 x12 x22 in1 in2 
# 2 19 2000 20 2001 20 21 
# 3 30 1998 32 2000 32 33 
+0

这也似乎运作良好,但我会问我上面问了Carl Witthoft的问题:将此用于大型矩阵也是不明智的,还是应该以某种方式更改它? – hejseb 2015-03-31 12:09:02

+0

与我的解决方案基本相同 - 伟大的思想等:-) – 2015-03-31 13:57:46

+0

@CarlWitthoft如果需要我会合并到你的答案,我只是不能让你的代码工作,再加上你正在使用'|'操作符。此外,那1 upvote是从我:) – zx8754 2015-03-31 14:19:33

相关问题