2010-12-13 50 views
3

我重新編碼嘗試組合的條件

df$test[(df$1st==(1:3) & df$2nd <= 4)] <- 1 
df$test[(df$1st==(1:3) & df$2nd <= 5)] <- 2 
df$test[(df$1st==(1:3) & df$2nd <= 6)] <- 3 

導致"longer object length is not a multiple of shorter object length"預警和df$test很多NA S,即使一些重新編碼正常工作。
我錯過了什麼?任何幫助讚賞。

DW

回答

4

我不知道你想實現與df$1st==(1:3)什麼,但它可能不會做你認爲它。它recyclesc(1,2,3)儘可能多的時間,使其只要df

如果你想檢查是否df$1st是1和3之間,你可能想拼出來:

df$1st>=1 & df$1st<=3 
+0

非常感謝aix!問題確實是1:3;拼寫出來工作。 – dw006 2010-12-13 11:58:35

+0

+1供參考。 – Marek 2010-12-13 14:05:30

5

問題是在這一行:

df$1st==(1:3) 

你可以使用%in%

df$1st %in% (1:3) 

警告來了,因爲你比較不同長度的向量(1:3有長度3和df$1st有長度「只有你知道什麼」)。

身邊我想你錯過了你的價值觀將被覆蓋:df$2nd <= 4df$2nd <= 6因此所有1和2是由覆蓋3

+0

對不起,覆蓋只發生在我的例子中,我放下了太快和錯誤... – dw006 2010-12-13 12:00:42

1

您可能還需要考慮使用transform()處理重新編碼此類問題。 transform()將執行比邏輯索引方法慢的速度,但更容易消化代碼的意圖。關於不同方法的優缺點可以參考here。試想一下:

set.seed(42) 
df <- data.frame("first" = sample(1:5, 10e5, TRUE), "second" = sample(4:8, 10e5, TRUE)) 

df <- transform(df 
    , test =  ifelse(first %in% 1:3 & second == 4, 1 
      , ifelse(first %in% 1:3 & second == 5, 2 
      , ifelse(first %in% 1:3 & second == 6, 3, NA))) 
    ) 

其次,列名1st2nd不是語法有效的列名。查看make.names()瞭解有效列名稱的更多詳細信息。使用data.frame時,可以使用/濫用check.names參數。例如:

> df <- data.frame("1st" = sample(1:5, 10e5, TRUE), "2nd" = sample(4:8, 10e5, TRUE), check.names = FALSE) 
> colnames(df) 
[1] "1st" "2nd" 
> df <- data.frame("1st" = sample(1:5, 10e5, TRUE), "2nd" = sample(4:8, 10e5, TRUE), check.names = TRUE) 
> colnames(df) 
[1] "X1st" "X2nd"