![](/img/trans.png)
[英]R Applying user defined function to vector; Indexing within sapply()
[英]How to sapply a vector on a user defined function in R
我有一个名为make_data
用于创建数据集。 我需要使用make _data
_data 和mu_1 <- seq(1:3)
生成 3 个不同的数据集。 我不知道如何使用sapply
,因为make_data
function 有多个 arguments,
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
与您的make_data
mu_1
中的 mu_1 位置匹配,而是与n
参数匹配。 要将参数传递给 function 中的“非第一个”参数,其中所有其他参数在定义中都有可接受的默认值,您需要将该“乱序”参数封装在匿名 function 中,然后将其作为命名参数接受:
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
由于其“简化”过程(即sapply
中的s
)而删除了它们。 您应该改用lapply
。 然后,这将为您提供命名数据框,它们将嵌入您可以正确迭代的列表结构中,而不是sapply
的“简化”结果:
dat_3<- lapply(mu_1, function(x) make_data(mu_1=x))
我开始认为我会通过部署traceback()
并展示如何调试和基本上扩展评论来回答这个问题,但这让我无处可去。 我意识到sapply
/ lapply
对命名对象的操作是问题的根源。 这是一个让许多R的新老用户感到沮丧的绊脚石。 只有值而不是名称被传递给 function。 正确接受 arguments 的责任完全留给用户。 甚至注定第一个参数的值的名称也无法通过。 当你“说” lapply(obj_name, FUN)
......事实证明FUN
没有得到obj_name
,而只有eval(objname)
的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.