我有一个用户定义的函数,叫做 make_data
创建数据集.我需要生成3个不同的数据集,使用的是 make _data
和 mu_1 <- seq(1:3)
. 我不知道如何使用 sapply
,因为 make_data
函数有多个参数。
library(dplyr) # for `%>%` and `slice`
library(caret) # for createDataPartion
make_data <- function(n = 1000, p = 0.5,
mu_0 = 0, mu_1 = 2,
sigma_0 = 1, sigma_1 = 1){
y <- rbinom(n, 1, p)
f_0 <- rnorm(n, mu_0, sigma_0)
f_1 <- rnorm(n, mu_1, sigma_1)
x <- ifelse(y == 1, f_1, f_0)
test_index <- createDataPartition(y, times = 1, p = 0.5, list = FALSE)
list(train = data.frame(x = x, y = as.factor(y)) %>% slice(-test_index),
test = data.frame(x = x, y = as.factor(y)) %>% slice(test_index))
}
mu_1 <- seq(0, 3)
dat_3<- sapply(mu_1,make_data)
我得到一个错误报告,如下所示。
错误在
createDataPartition(y, times = 1, p = 0.5, list = FALSE)
: y必须至少有2个数据点。
你的错误产生是因为你的论点。mu_1
正在进行位置匹配,而不是向 mu_1
在你 make_data
函数,而是向 n
参数。要在一个函数中向一个 "非第一 "参数传递一个参数,而其他参数在定义中都有可接受的默认值,你需要将这个 "非序列 "参数封装在一个匿名函数中,然后将其作为一个命名参数接受。
library(dplyr) # for `%>%` and `slice`
library(caret) # for createDataPartion
# your code here
dat_3<- sapply(mu_1, function(param) make_data(mu_1=param)) #succeeds
这个 n
参数现在是1000,这显然是你想要的。
str(dat_3)
List of 8
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] 2.963 0.313 0.853 -1.154 -1.895 ...
..$ y: Factor w/ 2 levels "0","1": 1 1 2 2 1 2 2 1 2 2 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] -1.288 1.245 -0.109 -0.794 0.11 ...
..$ y: Factor w/ 2 levels "0","1": 2 1 2 1 1 1 1 1 2 1 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] -0.686 1.823 -0.052 1.189 -0.318 ...
..$ y: Factor w/ 2 levels "0","1": 2 2 1 1 1 1 1 2 1 1 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] -0.623 0.311 1.298 0.848 1.17 ...
..$ y: Factor w/ 2 levels "0","1": 2 1 2 1 1 2 1 2 2 1 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] 0.956 0.825 1.592 2.729 -0.299 ...
..$ y: Factor w/ 2 levels "0","1": 2 1 1 2 1 1 1 1 1 1 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] 1.92059 3.29866 0.00569 0.38111 0.41855 ...
..$ y: Factor w/ 2 levels "0","1": 2 2 2 1 1 2 2 2 1 1 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] 4.572 3.19 -0.598 3.744 0.463 ...
..$ y: Factor w/ 2 levels "0","1": 2 2 1 2 1 2 1 1 2 2 ...
$ :'data.frame': 500 obs. of 2 variables:
..$ x: num [1:500] 2.7439 -0.0985 -0.4698 -1.2808 0.6663 ...
..$ y: Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 1 ...
- attr(*, "dim")= int [1:2] 2 4
- attr(*, "dimnames")=List of 2
..$ : chr [1:2] "train" "test"
..$ : NULL
这消除了错误,但数据集没有得到你想要的名字。这是因为 sapply
由于它的 "简化 "过程而删除了它们(这是它的 "简化 "过程)。s
在 sapply
). 您应该使用 lapply
. 这样你就可以得到命名的数据框,它们将被嵌入到一个列表结构中,你可以正确地进行迭代,而不是来自于 sapply
:
dat_3<- lapply(mu_1, function(x) make_data(mu_1=x))
我一开始以为我会通过以下方式来回答这个问题。traceback()
并展示了如何调试和基本扩展注释,但这让我毫无收获。我意识到 sapply
lapply
命名对象上的函数是问题的根源。这是一个绊脚石,让许多R的新老用户感到沮丧。 只有值而不是名称被传递给函数。除了第一个参数外,正确接受任何参数的责任完全由用户承担。甚至连注定要传给第一个参数的值的名字也不能通过。当你 "说" lapply(obj_name, FUN)
...原来 FUN
不得到 obj_name
只不过 eval(objname)
.