2015-03-31 53 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

相關問題