我的工作mclapply从multicore包(在Ubuntu),我正在写需要的是结果的函数mclapply(x, f),以便返回(也就是f(x[1]), f(x[2]), ...., f(x[n])).
# multicore doesn't work on Windows
require(multicore)
unlist(mclapply(
1:10,
function(x){
Sys.sleep(sample(1:5, size = 1))
identity(x)}, mc.cores = 2))
[1] 1 2 3 4 5 6 7 8 9 10
Run Code Online (Sandbox Code Playgroud)
上面的代码似乎暗示mclapply返回的结果顺序与lapply.
但是,如果这个假设是错误的,我将不得不花费很长时间来重构我的代码,所以我希望得到更熟悉这个包/并行计算的人的保证,这个假设是正确的.
是否可以安全地假设mclapply始终按顺序返回结果,而不管它是否给出了可选参数?
我知道在大多数情况下,虚拟的pairlists不会在核心语言之外使用,但是我认为它们在内部使用而不是泛型向量是有原因的.
为什么在R内部使用滑翔伞,在自己的功能中使用滑翔伞有什么性能优势?
我有一个数字向量列表,我需要创建一个只包含每个向量的一个副本的列表.对于相同的函数没有列表方法,所以我编写了一个函数来应用于检查每个向量与其他向量.
F1 <- function(x){
to_remove <- c()
for(i in 1:length(x)){
for(j in 1:length(x)){
if(i!=j && identical(x[[i]], x[[j]]) to_remove <- c(to_remove,j)
}
}
if(is.null(to_remove)) x else x[-c(to_remove)]
}
Run Code Online (Sandbox Code Playgroud)
问题是随着输入列表x的大小增加,此函数变得非常慢,部分原因是for循环分配了两个大向量.我希望有一种方法可以在一分钟内运行,长度为150万的列表,长度为15的向量,但这可能是乐观的.
有没有人知道比较列表中的每个向量与每个其他向量的更有效方法?矢量本身的长度保证相等.
样本输出如下所示.
x = list(1:4, 1:4, 2:5, 3:6)
F1(x)
> list(1:4, 2:5, 3:6)
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数来捕获它所调用的函数的参数.例如,
get_args <- function () as.list( sys.call(sys.parent()) )[-1]
caller <- function (x, y, z) {
get_args()
}
caller(1,2,3)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
Run Code Online (Sandbox Code Playgroud)
不幸的是,sys.call()没有添加带参数值的匹配参数名称,我想写一个类似版本的get_args,返回类似于的输出
caller2 <- function (x, y, z) {
as.list( match.call() )[-1]
}
caller2(1,2,3)
$x
[1] 1
$y
[1] 2
$z
[1] 3
Run Code Online (Sandbox Code Playgroud)
直接用"match.call()"替换"get_args()"不是我正在寻找的解决方案,因为实际上get_args在返回其父函数参数之前会做一些其他事情.
我试过用几种方式将match.call()与sys.parent()一起使用,但是我无法让函数返回调用者的参数; 它只返回get_args()的参数.
对于上面的测试用例,有没有办法让get_args()返回与caller2相同的输出?我知道使用formals()手动命名参数是可能的,但这是否保证是公平的?
如果需要澄清,请在下面留言.谢谢.
编辑1:
get_args()的目的是充当用户友好的方式来获取调用函数的参数.键入as.list(match.call())[ - 1]会变旧,但因为match.call抓取最近的函数调用,所以此刻它只获取get_args()的参数.
get_args()也将从父函数中获取默认参数,但这很容易实现.
解:
感谢Hong Ooi,使用match.call的关键似乎是提供你想要了解的函数的调用和定义.对于后代来说,稍微修改一下,匿名友好的get_args版本
get_args <- function () {
as.list( match.call(
def = sys.function( -1 ),
call = sys.call(-1)) )[-1] …Run Code Online (Sandbox Code Playgroud) 我正在为R编写一个包,其中导出的函数由高阶函数修饰,该函数添加了错误检查和一些其他样板代码.
但是,因为此代码位于顶层,所以在解析后会对其进行评估.这意味着包文件的加载顺序很重要.
为了给出一个等效但简化的示例,假设我有一个包含两个文件的包(Negate2和Utils),并且我需要首先加载Negate2.R,以便定义函数'isfalse()'而不会抛出错误.
# /Negate2.R
Negate2 <- Negate
# -------------------
# /Utils.R
istrue <- isTRUE
isfalse <- Negate2(istrue)
Run Code Online (Sandbox Code Playgroud)
是否可以构建NAMESPACE,DESCRIPTION(整理)或其他包文件以更改文件的加载顺序?R包结构和CRAN的内部工作对我来说仍然是黑魔法.
使用笨拙的黑客可以解决这个问题,但解决这个问题的重复性最小的方法.包装函数必须是高阶函数,因为它还会更改其输入函数的函数调用语义.这个包很重(大约6000行,100个函数),所以重复会有问题.
正如@Manetheran所指出的,要更改加载顺序,只需更改DESCRIPTION文件中文件名的顺序即可.
# /DESCRIPTION
Collate:
'Negate2.R'
'Utils.R'
Run Code Online (Sandbox Code Playgroud) 有没有人知道如何编写一个函数F,它接受函数调用(例如,mean(x = 1:10))作为参数,并返回被调用函数的名称(mean)?
到目前为止,我的最佳尝试总结如下
(function(x1){
return(deparse(substitute(x1)))
})(mean(x = 1:10))
### 'mean(x = 1:10)'
Run Code Online (Sandbox Code Playgroud)
在解析之前将x1(函数调用)更改为表达式似乎没有多大帮助:返回
(function(x1){
return(deparse(as.expression(substitute(x1))))
})(mean(x = 1:10))
# "expression(mean(x = 1:10))"
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我想可以使用匿名函数作为参数太多,所以˚F应该返回(函数(x)的打印(X))的(函数(x)的打印(X))(1).如果您需要任何澄清,请随时发表评论.谢谢.
edit1:请注意,我想避免检查第一个括号并删除它之前的代码(对于"mean(x = 1:10)"将返回"mean"),作为"bad(Fun_nAme")实际上是R中的合法函数名.
问题回答: Josh O'Brien的答案很完美:满足上述条件的函数F是
F <- function(x) deparse(substitute(x)[[1]])
Run Code Online (Sandbox Code Playgroud)
它适用于二元运算符,标准函数和匿名函数.
我正在尝试编写一个程序,它将表达式作为输入,并返回一个函数,该表达式绑定为它的主体.
caller <- function (expr, params) {
Function <- function (params, body, env = parent.frame()) {
# returns a function
}
Function(params, body = expr)
}
func <- caller (a + b, c('a', 'b'))
func(1, 2)
[1] 3
Run Code Online (Sandbox Code Playgroud)
我可以通过使用类似的东西很容易地绑定参数
params <- c('a', 'b')
f <- function() {}
formals(f) <- structure(
replicate(length(params), NULL),
names = params
)
Run Code Online (Sandbox Code Playgroud)
我无法想出一种动态添加表达式作为正文的方法.我已经尝试过使用substitute(),并从pryr库中调整make_function,但是我无法完成任务.我最好的尝试是
body(f, parent.frame()) <- as.list( match.call() )[-1]$body
Run Code Online (Sandbox Code Playgroud)
我也无法用替代品来解决这个问题.关于如何绑定主体以使最顶层的程序按预期工作的任何想法?
我在SO上看到了类似的问题,但解决方案似乎并不能解决这个问题.
我正在尝试查找在任意合法 R 表达式中使用的所有函数的名称,但我找不到将以下示例标记为函数而不是名称的函数。
test <- expression(
this_is_a_function <- function(var1, var2){
this_is_a_function(var1-1, var2)
})
all.vars(test, functions = FALSE)
[1] "this_is_a_function" "var1" "var2"
Run Code Online (Sandbox Code Playgroud)
all.vars(expr, functions = FALSE) 似乎在表达式中返回函数声明 (f <- function(){}),同时过滤掉函数调用 ('+'(1,2), ...)。
是否有任何函数 - 在核心库或其他地方 - 会将“this_is_a_function”标记为函数,而不是名称?它需要处理语法上合法但可能无法正确评估的任意表达式(例如'+'(1,'duck'))
我发现了类似的问题,但它们似乎不包含解决方案。
如果需要澄清,请在下面发表评论。我正在使用解析器包来解析表达式。
我有包含整个脚本的表达式,这些脚本通常由一个包含嵌套函数定义的 main 函数组成,并在脚本末尾调用 main 函数。
函数都在表达式中定义,我不介意是否必须包含 '<-' 和 '{',因为我可以自己轻松地将它们过滤掉。
动机是获取我所有的 R 脚本并收集有关我对函数的使用如何随时间变化的基本统计数据。
基于正则表达式的方法获取函数定义,结合 James 注释中的方法获取函数调用。通常有效,因为我从不使用右手赋值。
function_usage <- function(code_string){
# takes a script, extracts function definitions
require(stringr)
code_string <- str_replace(code_string, 'expression\\(', '')
equal_assign <- '.+[ \n]+<-[ \n]+function'
arrow_assign <- …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何获得R的callCC函数来短路函数的评估,以便与lapply和Reduce等函数一起工作.
动机
这将使Reduce和lapply具有渐近效率> O(n),允许您提前退出计算.
例如,如果我在列表中搜索一个值,我可以在列表中映射一个'finder'函数,第二个找到lapply停止运行并返回该值(就像打破一个循环,或者使用一个返回声明提前爆发).
问题是我在使用callCC需要的样式编写lapply和Reduce应该使用的函数时遇到问题.
例
假设我正在尝试编写一个函数来在列表中找到值'100':相当于
imperativeVersion <- function (xs) {
for (val in xs) if (val == 100) return (val)
}
Run Code Online (Sandbox Code Playgroud)
传递给lapply的函数如下所示:
find100 <- function (val) { if (val == 100) SHORT_CIRCUIT(val) }
functionalVersion <- function (xs) lapply(xs, find100)
Run Code Online (Sandbox Code Playgroud)
这(显然)崩溃,因为短路功能尚未定义.
callCC( function (SHORT_CIRCUIT) lapply(1:1000, find100) )
Run Code Online (Sandbox Code Playgroud)
问题是这也会崩溃,因为当定义了find100时,短路功能并不存在.我想要类似的东西工作.
以下是有效的,因为SHORT_CIRCUIT是在创建传递给lapply的函数时定义的.
callCC(
function (SHORT_CIRCUIT) {
lapply(1:1000, function (val) {
if (val == 100) SHORT_CIRCUIT(val)
})
)
Run Code Online (Sandbox Code Playgroud)
如何在传递给lapply的函数中定义SHORT_CIRCUIT而不像上面那样定义内联?
我知道这个例子可以使用循环,减少或任何其他方式来实现.我正在寻找解决使用callCC与lapply和Reduce的具体问题的解决方案.
如果我含糊不清或需要任何澄清,请在下面留言.我希望有人可以帮忙:)
编辑一:方法应该是'生产质量'; 没有贬值功能或类似的黑魔法.
任何人都可以帮助我提高这个R代码的效率吗?
我正在尝试编写一个函数,将字符串列表更改为字符串向量,或将数字列表更改为数字向量,将类型元素列表更改为某种类型的向量.
我希望能够将列表更改为特定类型的向量,如果它们具有以下属性:
它们是均匀打字的.列表的每个元素都是"字符"类型,或"复杂"等.
列表的每个元素都是长度为1.
as_atomic <- local({
assert_is_valid_elem <- function (elem, mode) {
if (length(elem) != 1 || !is(elem, mode)) {
stop("")
}
TRUE
}
function (coll, mode) {
if (length(coll) == 0) {
vector(mode)
} else {
# check that the generic vector is composed only
# of length-one values, and each value has the correct type.
# uses more memory that 'for', but is presumably faster.
vapply(coll, assert_is_valid_elem, logical(1), mode = mode)
as.vector(coll, mode = mode)
} …Run Code Online (Sandbox Code Playgroud)是否有任何重要的 [1] 理由不导出具有表单名称的函数。fnname在 R 包中?
我知道点前缀变量的主要用途是在使用诸如 之类的函数搜索环境时将变量表示为隐藏ls,并表示对象或列表中的字段应像 S4 .Data 字段一样被视为私有.
test_env <- new.env(parent = emptyenv())
test_env $ .hidden <- 10
ls(test_env)
# character(0)
ls(test_env, all.names = TRUE)
# ".hidden"
Run Code Online (Sandbox Code Playgroud)
据我所知,该约定是在一些实用程序环境搜索函数的级别上执行的,但并未在整个 R 语言中执行。
变量的点前缀是否会改变核心语言特征的行为,如词法范围或各种对象系统,如果是这样,这是否会使导出点前缀函数变得不合适或危险?
感谢您提供的任何帮助或信息。
[1] 意义重大我的意思是非文体;有问题的库使用特殊的前缀和后缀来标记函数类型签名的各个方面,有点像plyr的特殊命名约定。滥用点前缀变量通常是非语义的,但在这种情况下,值得复合含义。
我正在尝试将变量true,false,na和null的Pascal-Case版本分配到我的R包中.这很容易做到,但我也想锁定绑定以防止重命名变量.
# An anti-example from the base libraries
F <- TRUE
T <- FALSE
T && T
FALSE
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何锁定包中的变量以防止进一步修改.以下mock包不起作用
# test.R
True <- TRUE
lockBinding('True', environment())
#DESCRIPTION
Collate:
'test.R'
Run Code Online (Sandbox Code Playgroud)
运行R CMD检查时出现以下错误:
Error in eval(expr, envir, enclos) :
cannot change value of locked binding for 'True'
Run Code Online (Sandbox Code Playgroud)
锁定R包变量的正确方法是什么,因此无法重新分配?
编辑:包含错误的错误消息.
我是一个相对绿色的Rcpp用户,我不确定如何测试两个值是否相同.
例如,以下函数用于测试值是否包含在列表中,但是对于简单测试用例返回不正确的结果
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
LogicalVector is_member (SEXP val, List coll) {
int coll_len = coll.size();
if (coll_len == 0) {
return LogicalVector::create();
} else {
Function identical("identical");
for (int ith = 0; ith < coll_len; ++ith) {
SEXP elem = coll[ith];
if (identical(val, elem)) {
return true;
}
}
return false;
}
}
is_member(1L, list(1L))
# FALSE
is_member(NaN, list(NaN, NaN))
# False
Run Code Online (Sandbox Code Playgroud)
为什么会这样,以及如何使用相同的极端情况和基本功能"相同"的持久性来测试身份?我找不到任何Rcpp糖用于此目的,但是如果我找不到直接解决方案,我怀疑无序集或者可能使用唯一函数来测试身份.
如果我的C++是非惯用的/危险的,我也会感激反馈,如果我一直含糊不清,请在下面留言,我会修改我的问题.
谢谢
r ×13
function ×2
package ×2
performance ×2
benchmarking ×1
build ×1
call ×1
const ×1
eval ×1
expression ×1
list ×1
multicore ×1
rcpp ×1
substitution ×1
vector ×1