2011-06-10 112 views
11

我想從函數返回一個data.frame如果爲TRUE,否則返回NA使用return(ifelse(condition, mydf, NA))爲什麼ifelse將data.frame轉換爲列表:ifelse(TRUE,data.frame(1),0))!= data.frame(1)?

但是,ifelse會從data.frame中去除列名。

這些結果爲什麼不同?

> data.frame(1) 
    X1 
1 1 
> ifelse(TRUE, data.frame(1), NA) 
[[1]] 
[1] 1 

從dput()的一些附加洞察:

> dput(ifelse(TRUE, data.frame(1), 0)) 
list(1) 
> dput(data.frame(1)) 
structure(list(X1 = 1), .Names = "X1", row.names = c(NA, -1L), 
      class = "data.frame") 

回答

14

ifelse通常旨在用於向量化的比較,並且具有副作用如這些:當它在?ifelse說,

‘ifelse’ returns a value with the same shape as ‘test’ ... 

所以在這種情況下(test是一個長度爲1的向量)它試圖將數據幀轉換爲長度爲1的'向量'(此例中爲列表)...

return(if (condition) mydf else NA) 

作爲一般的設計點我嘗試返回相同結構的對象不管是什麼,所以我可能更喜歡

if (!condition) mydf[] <- NA 
return(mydf) 

作爲一般規則,我覺得是R用戶(尤其是來自哪裏其他編程語言)首先專門使用if,花一些時間發現ifelse,然後過度使用它一段時間,稍後發現您確實想要在邏輯上下文中使用if。類似的事情發生在&&&

參見:

+0

@Ben謝謝你的提示。我不知道'mydf [] < - NA'是一個選項。 – 2011-06-10 19:07:31

+0

@Ben我會在後續的函數中將if(is.na(myfn()))的用法改爲if(sum(is.na(myfn())> 0)'嗎?如果你需要澄清,單獨的問題。 – 2011-06-10 19:11:58

+1

可能只是'如果(所有(is.na(mydf)))'? – 2011-06-10 19:14:45