2017-07-24 94 views
0

使用接受向量,靜態值和NULL s的參數向量化R函數的最佳方法是什麼?我遇到一個問題,當我Map()函數的參數有時提供NULL s。我得到下列錯誤消息(複製使用下面的代碼):如何使用可以用NULL值提供的參數矢量化R函數?

Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) : zero-length inputs cannot be mixed with those of non-zero length

要複製這個問題,我已經寫了從data任選實施minmax值返回使用參數n模擬值的函數。

#' foo (example function with some args defaulting to NULL) 
#' 
#' Returns simulated normal values using population parameters from data 
#' 
#' @param data Numeric vector used to calculate population parameters 
#' @param n Number of simulated data points to return 
#' @param min Optional. Creates a truncation effect. Simulated values 
#' below min will be replaced with min. 
#' @param max Optional. Creates a truncation effect. Simulated values 
#' above max will be replaced with max. 
#' @return Numeric vector of simulated values. 
foo <- function(data, n, min = NULL, max = NULL) { 
    x <- rnorm(n, mean(data), sd(data)) 
    if (!is.null(min)) { 
    x[x < min] <- min 
    } 
    if (!is.null(max)) { 
    x[x > max] <- max 
    } 
    x 
} 

我正在處理列表並希望函數返回列表。所以,在這裏,數據向量是一個數值向量列表。

## data vector 
data <- replicate(5, rnorm(3), simplify = FALSE) 

其他參數可以接受靜態(length(x) == 1)或動態值(length(x) == length(data))。當提供非NULL值時,無論args是給定一個還是多個值,它都可以工作。

## static args (this works) 
n <- 10 
min <- -1.96 
max <- 1.96 
Map(foo, data, n, min, max) 

## vector args (this works) 
n <- sample(2:100, 5) 
min <- runif(5, -4, -1) 
max <- runif(5, 1, 4) 
Map(foo, data, n, min, max) 

但是,當參數通過一個NULL價值它打破。

## null args (this doesn't work) 
n <- sample(2:100, 5) 
min <- NULL 
max <- NULL 
Map(foo, data, n, min, max) 

## it doesn't matter if n is a vector 
n <- 10 
min <- NULL 
max <- NULL 
Map(foo, data, n, min, max) 


Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) : 
    zero-length inputs cannot be mixed with those of non-zero length 
+0

你想在你的輸入列表中使用每個向量的「mean」還是* all * v的「mean」輸入列表中的ectors(聚合)? – CPak

+0

這不是我正在嘗試修復的實際功能,但相當於假定我想單獨使用每個矢量。 – mkearney

+2

因爲在你的函數中,你聲明'min = NULL'和'max = NULL',你可以在你的調用中不傳遞'min'和'max'。使用'Map(foo,data,10)'適用於我。 – CPak

回答

4

我認爲你正在尋找的代碼是

n <- sample(2:100, 5) 
min <- list(NULL) 
max <- list(NULL) 
Map(foo, data, n, min, max) 

Map函數需要的功能之後的每個參數是一個向量或參數列表,這將回收到的長度最長的一個。所以在這種情況下,我們有length(data)length(n)等於5,length(min)length(max)等於1,因此最小和最大列表中的單個NULL被循環使用5次並每次傳遞給函數。或者,如果你想做一個類似於「apply」的操作,其中一些參數是向量而另一些是標量(例如,要傳遞給函數的每個調用的單個值),使用mapply,直接向量傳遞args和內MoreArgs標ARGS:

n <- sample(2:100, 5) 
min <- NULL 
max <- NULL 
mapply(foo, data, n, MoreArgs=list(min, max)) 

(另外,我沒有這樣做,在這裏與您的代碼的一致性,但你應該總是傳遞參數適用類型與名稱的功能(例如MoreArgs=list(min=min, max=max)

相關問題