簡體   English   中英

是否可以將 na.rm 全局設置為 TRUE?

[英]Is it possible to set na.rm to TRUE globally?

對於像max的命令,選項na.rm默認設置為FALSE 我理解為什么這是一個好主意,但我想可逆地關閉它一段時間 - 即在會話期間。

我怎樣才能要求 R 設置na.rm = TRUE每當它是一個選項? 我發現

options(na.action = na.omit)

但這不起作用。 我知道我可以為我編寫的每個函數設置一個na.rm=TRUE選項。

my.max <- function(x) {max(x, na.rm=TRUE)}

但這不是我要找的。 我想知道是否有什么我可以在全球/普遍上做更多的事情,而不是為每個功能做。

一種解決方法(危險)是執行以下操作:

  1. 列出所有以na.rm作為參數的函數。 在這里,我將搜索限制在基本包中。
  2. 獲取每個函數並在其主體的開頭添加這一行: na.rm = TRUE
  3. 將該功能分配回基礎包。

所以首先我將所有以na.rm作為參數的函數存儲在一個列表 (ll) 中:

uses_arg <- function(x,arg) 
  is.function(fx <- get(x)) && 
  arg %in% names(formals(fx))
basevals <- ls(pos="package:base")      
na.rm.f <- basevals[sapply(basevals,uses_arg,'na.rm')]

編輯更好的方法來獲取所有 na.rm 的參數函數(感謝 mnel 評論)

Funs <- Filter(is.function,sapply(ls(baseenv()),get,baseenv()))
na.rm.f <- names(Filter(function(x) any(names(formals(args(x)))%in% 'na.rm'),Funs))

所以na.rm.f列表看起來像:

 [1] "all"                     "any"                     "colMeans"                "colSums"                
 [5] "is.unsorted"             "max"                     "mean.default"            "min"                    
 [9] "pmax"                    "pmax.int"                "pmin"                    "pmin.int"               
[13] "prod"                    "range"                   "range.default"           "rowMeans"               
[17] "rowsum.data.frame"       "rowsum.default"          "rowSums"                 "sum"                    
[21] "Summary.data.frame"      "Summary.Date"            "Summary.difftime"        "Summary.factor"         
[25] "Summary.numeric_version" "Summary.ordered"         "Summary.POSIXct"         "Summary.POSIXlt" 

然后對於我更改主體的每個函數,代碼的靈感來自data.table包(常見問題解答 2.23),該包在rbind.data.framecbind.data.frame的開頭添加一行。

ll <- lapply(na.rm.f,function(x)
  {
  tt <- get(x)
  ss = body(tt)
  if (class(ss)!="{") ss = as.call(c(as.name("{"), ss))
  if(length(ss) < 2) print(x)
  else{
    if (!length(grep("na.rm = TRUE",ss[[2]],fixed=TRUE))) {
      ss = ss[c(1,NA,2:length(ss))]
      ss[[2]] = parse(text="na.rm = TRUE")[[1]]
      body(tt)=ss
      (unlockBinding)(x,baseenv())
      assign(x,tt,envir=asNamespace("base"),inherits=FALSE)
      lockBinding(x,baseenv())
      }
    }
  })

不,如果你檢查,我們列表的每個函數的第一行:

unique(lapply(na.rm.f,function(x) body(get(x))[[2]]))
[[1]]
na.rm = TRUE

不可能將na.rm全局更改為TRUE (請參閱Hong Ooi 在問題下的評論。)

編輯:

不幸的是,您不想要的答案是唯一普遍有效的答案。 沒有像 na.action 那樣的全局選項,它只影響 lm、glm 等建模功能(即使在那里,也不能保證在所有情況下都能工作)。 – Hong Ooi 2013 年 7 月 2 日 6:23

對於我的 R 包,我覆蓋了現有的函數meansum 感謝偉大的 Ben(下面的評論),我改變了我的功能:

mean <- function(x, ..., na.rm = TRUE) {
  base::mean(x, ..., na.rm = na.rm)
}

在此之后, mean(c(2, NA, 3)) = 2.5而不是NA

對於sum

sum <- function(x, ..., na.rm = TRUE) {
  base::sum(x, ..., na.rm = na.rm)
}

這將產生sum(c(2, NA, 3)) = 5而不是NA

sum(c(2, NA, 3, NaN))也有效。

已經有幾個關於在全球范圍內更改na.rm參數的答案。 我只想注意purrrpryr包中的partial()函數。 使用此函數,您可以使用預定義參數創建現有函數的副本:

library(purrr)
.mean <- partial(mean, na.rm = TRUE)

# Create sample vector
df <- c(1, 2, 3, 4, NA, 6, 7)

mean(df)
>[1] NA

.mean(df)
>[1] 3.833333

我們可以將此提示與@agstudy 答案結合起來,並使用na.rm = TRUE參數創建所有函數的副本:

library(purrr)

# Create a vector of function names https://stackoverflow.com/a/17423072/9300556
Funs <- Filter(is.function,sapply(ls(baseenv()),get,baseenv()))
na.rm.f <- names(Filter(function(x) any(names(formals(args(x)))%in% 'na.rm'),Funs))

# Create strings. Dot "." is optional
fs <- lapply(na.rm.f,
             function(x) paste0(".", x, "=partial(", x ,", na.rm = T)"))

eval(parse(text = fs)) 

所以,現在有.all.min.max ,等我們.GlobalEnv 你可以運行它們:

.min(df)
> [1] 1
.max(df)
> [1] 7
.all(df)
> [1] TRUE

要覆蓋函數,只需刪除點“。” 從 lapply 電話。 受到這篇博文的啟發

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM