小编Rya*_*ell的帖子

mclapply是否保证按顺序返回结果?

我的工作mclapplymulticore包(在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始终按顺序返回结果,而不管它是否给出了可选参数?

parallel-processing multicore r

13
推荐指数
1
解决办法
2382
查看次数

什么时候在R使用pairlists?

我知道在大多数情况下,虚拟的pairlists不会在核心语言之外使用,但是我认为它们在内部使用而不是泛型向量是有原因的.

为什么在R内部使用滑翔伞,在自己的功能中使用滑翔伞有什么性能优势?

performance r

11
推荐指数
1
解决办法
1915
查看次数

有效地在列表中查找唯一的向量元素

我有一个数字向量列表,我需要创建一个只包含每个向量的一个副本的列表.对于相同的函数没有列表方法,所以我编写了一个函数来应用于检查每个向量与其他向量.

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)

r list vector

9
推荐指数
2
解决办法
2341
查看次数

使用名称获取R中父函数的参数

我正在尝试编写一个函数来捕获它所调用的函数的参数.例如,

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

8
推荐指数
1
解决办法
1512
查看次数

更改R包中文件的加载顺序

我正在为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)

r build package

7
推荐指数
1
解决办法
1510
查看次数

从函数调用中提取函数调用名称

有没有人知道如何编写一个函数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)

它适用于二元运算符,标准函数和匿名函数.

r function call

6
推荐指数
1
解决办法
171
查看次数

在R中捕获表达式作为函数体

我正在尝试编写一个程序,它将表达式作为输入,并返回一个函数,该表达式绑定为它的主体.

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上看到了类似的问题,但解决方案似乎并不能解决这个问题.

eval r metaprogramming substitution

6
推荐指数
1
解决办法
503
查看次数

在 R 表达式中查找所有函数的名称

我正在尝试查找在任意合法 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'))

我发现了类似的问题,但它们似乎不包含解决方案。

如果需要澄清,请在下面发表评论。我正在使用解析器包来解析表达式。

编辑:@Hadley

我有包含整个脚本的表达式,这些脚本通常由一个包含嵌套函数定义的 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)

expression r metaprogramming function

5
推荐指数
1
解决办法
303
查看次数

在R中使用具有高阶函数的callCC

我试图弄清楚如何获得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的具体问题的解决方案.

如果我含糊不清或需要任何澄清,请在下面留言.我希望有人可以帮忙:)

编辑一:方法应该是'生产质量'; 没有贬值功能或类似的黑魔法.

continuations functional-programming r

5
推荐指数
1
解决办法
165
查看次数

有效转换为R中的向量

任何人都可以帮助我提高这个R代码的效率吗?

我正在尝试编写一个函数,将字符串列表更改为字符串向量,或将数字列表更改为数字向量,将类型元素列表更改为某种类型的向量.

我希望能够将列表更改为特定类型的向量,如果它们具有以下属性:

  1. 它们是均匀打字的.列表的每个元素都是"字符"类型,或"复杂"等.

  2. 列表的每个元素都是长度为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)

performance benchmarking r microbenchmark

5
推荐指数
1
解决办法
1865
查看次数

隐藏变量在 R 中的表现如何?

是否有任何重要的 [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的特殊命名约定。滥用点前缀变量通常是非语义的,但在这种情况下,值得复合含义。

r

5
推荐指数
0
解决办法
1514
查看次数

在R包中分配锁定变量

我正在尝试将变量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包变量的正确方法是什么,因此无法重新分配?

编辑:包含错误的错误消息.

r const package

4
推荐指数
1
解决办法
5361
查看次数

在Rcpp中测试价值身份

我是一个相对绿色的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 rcpp

2
推荐指数
1
解决办法
98
查看次数