r - 从 R 中的 CSV 文件中读取“...”中定义的函数输入值
问题描述
假设我有一个foo
如下所示的 R 函数。该函数有 4 个固定参数,以及在...
.
参数的所有输入值foo
都存储在这个CSV 文件中。
在下面的代码中,我可以在循环foo
中使用从 CSV 文件导入的 4 个固定参数成功运行。但是我想知道如何插入命令中定义的参数?lapply
...
lapply
foo <- function(n = NULL, r = NULL, post, control, ...){ ## the function
data.frame(n = n, r = r, post, control, ...)
}
D <- read.csv("https://raw.githubusercontent.com/izeh/i/master/j.csv", h = T) # CSV file
L <- split(D, D$study.name) ; L[[1]] <- NULL
# the fixed args values:
n <- lapply(1:length(L), function(i) L[[i]]$n)
r <- lapply(1:length(L), function(i) L[[i]]$r)
post <- lapply(1:length(L), function(i) L[[i]]$post)
control <- lapply(1:length(L), function(i) L[[i]]$control)
# names of args defined in `...`:
dot.names <- names(L[[1]])[!names(L[[1]]) %in% formalArgs(foo)][-1]
# the `...` args values:
a <- lapply(dot.names, function(i) lapply(L, function(j) j[grep(i, names(j))]))
## RUN `foo` function:
lapply(1:length(L), function(i) foo(n = n[[i]], r = r[[i]], post = post[[i]],
control = control[[i]])) # BUT! how can I insert the
# arguments defined in `...`
# in the function?
解决方案
我们也可以使用Map
with do.call
。我们可以通过提取列 'n'、'r'、'post'、control' 和基于 'dot.names' 的输出的额外列 ( )foo
在一次调用中提取参数,然后(来自-或使用与此处提到的相同的方法)并将其传递lapply
...
transpose
purrr
Map
args <- lapply(L, function(x) unclass(x[c("n", "r", "post", "control", dot.names)]))
library(purrr)
unname(do.call(Map, c(f = foo, transpose(args))))
#[[1]]
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 1 2 0 1
#2 13 0.5 2 FALSE 1 2 0 1
#3 15 0.5 1 FALSE 1 2 0 1
#4 15 0.5 2 FALSE 1 2 0 1
#5 16 0.5 1 TRUE 1 2 0 1
#6 16 0.5 2 TRUE 1 2 0 1
#[[2]]
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 0 1 1 0
#2 13 0.5 2 FALSE 0 1 1 0
#3 15 0.5 1 FALSE 0 1 1 0
#4 15 0.5 2 FALSE 0 1 1 0
#5 16 0.5 1 TRUE 0 1 1 0
#6 16 0.5 2 TRUE 0 1 1 0
#[[3]]
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 1 3 0 1
#2 13 0.5 2 FALSE 1 3 0 1
#3 13 0.5 3 FALSE 1 3 0 1
#4 15 0.5 1 FALSE 1 3 0 1
#5 15 0.5 2 FALSE 1 3 0 1
#6 15 0.5 3 FALSE 1 3 0 1
#7 16 0.5 1 TRUE 1 3 0 1
#8 16 0.5 2 TRUE 1 3 0 1
#9 16 0.5 3 TRUE 1 3 0 1
OP提到了transpose
用一个base R
选项替换
m1 <- simplify2array(lapply(names(args[[1]]), function(nm)
lapply(args, function(l1) l1[nm])))
do.call(Map, c(f = foo, unname(split(m1, col(m1)))))
如果我们可以使用tidyverse
library(tidyverse)
map(L, ~
.x %>%
select(n, r, post, control, dot.names) %>%
as.list) %>%
transpose %>%
pmap(., foo)
#$Ellis.sh1
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 1 2 0 1
#2 13 0.5 2 FALSE 1 2 0 1
#3 15 0.5 1 FALSE 1 2 0 1
#4 15 0.5 2 FALSE 1 2 0 1
#5 16 0.5 1 TRUE 1 2 0 1
#6 16 0.5 2 TRUE 1 2 0 1
#$Goey1
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 0 1 1 0
#2 13 0.5 2 FALSE 0 1 1 0
#3 15 0.5 1 FALSE 0 1 1 0
#4 15 0.5 2 FALSE 0 1 1 0
#5 16 0.5 1 TRUE 0 1 1 0
#6 16 0.5 2 TRUE 0 1 1 0
#$kabla
# n r post control ESL prof scope type
#1 13 0.5 1 FALSE 1 3 0 1
#2 13 0.5 2 FALSE 1 3 0 1
#3 13 0.5 3 FALSE 1 3 0 1
#4 15 0.5 1 FALSE 1 3 0 1
#5 15 0.5 2 FALSE 1 3 0 1
#6 15 0.5 3 FALSE 1 3 0 1
#7 16 0.5 1 TRUE 1 3 0 1
#8 16 0.5 2 TRUE 1 3 0 1
#9 16 0.5 3 TRUE 1 3 0 1
更新
根据此处显示的示例,结构略有不同,因此我们可以将list
with names
(for base R
)转置
argsT <- setNames(lapply(names(args[[1]]),
function(nm) lapply(args, `[[`, nm)), names(args[[1]]))
out1 <- unname(do.call(Map, c(f = d.prepos, argsT)))
out2 <- unname(do.call(Map, c(f = d.prepos, purrr::transpose(args))))
identical(out1, out2)
#[1] TRUE
推荐阅读
- php - 如何从价格列(数据库)中获取两个最小值。[拉拉维尔]
- python - 在 Python 中的列表中保留项目的最新版本
- teradata - Teradata:在整数和单词之间预期类似“,”
- javascript - 没有小数的温度。21.01 > 21
- c++ - 作业左侧的功能问题
- javascript - 我可以在 Python 中创建类似 JavaScript 的对象吗
- ruby-on-rails - PG::UndefinedTable:错误:关系“条目”不存在
- .net - 在 UWP 中以短时间间隔运行简短的后台任务以应对特殊情况的报警场景
- algorithm - 如何使用带递归的方案将数字插入已排序的数字,合并后的数字仍然排序?((插入1245 3)-> 12345)
- java - 使用java中的正则表达式剥离或概括SQL字符串中的所有函数调用参数