执行标准回收规则

Bri*_*ggs 35 r

R的一个很好的特征与其固有的矢量化特性有关,它是2.2节中的R简介中描述的循环规则.

在同一表达式中出现的载体不必全部具有相同的长度.如果不是,则表达式的值是一个向量,其长度与表达式中出现的最长向量相同.表达式中较短的向量经常根据需要(可能是分数)再循环,直到它们与最长向量的长度匹配.特别是简单地重复常数.

大多数标准函数都使用它,但执行此操作的代码隐藏在底层C代码中.

是否有规范的方法来完全在R代码中实现函数的标准回收规则?也就是说,给定一个类似的功能

mock <- function(a, b, c) {
    # turn a, b, and c into appropriate recycled versions

    # do something with recycled a, b, and c in some appropriately vectorized way
}
Run Code Online (Sandbox Code Playgroud)

其中a,b和,c是否是可能具有不同长度和未知类型/类别的向量,是否有规范的方法来获得一组新的载体,这些载体根据标准回收规则进行回收?特别是,我不能假设"做某事"步骤本身会进行适当的回收,所以我需要事先自己做.

bap*_*ste 23

我以前用过这个,

expand_args <- function(...){
  dots <- list(...)
  max_length <- max(sapply(dots, length))
  lapply(dots, rep, length.out = max_length)
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ien 8

我可能会用这个length.out论点rep()去做大部分真正的工作.

这是一个创建一个better.data.frame()函数的例子(它应该被调用"better".data.frame()),它不会限制它作为参数传递的向量的长度.在这种情况下,我将所有载体回收到最长的载体长度,但您显然可以根据自己的回收需求进行调整!

better.data.frame <- function(...) {
    cols <- list(...)
    names(cols) <- sapply(as.list(match.call()), deparse)[-1]

    # Find the length of the longest vector
    # and then recycle all columns to that length.
    n <- max(sapply(cols, length))
    cols <- lapply(cols, rep, length.out = n)

    as.data.frame(cols)
}

# Try it out
a <- Sys.Date() + 0:9
b <- 1:3
c <- letters[1:4]

data.frame(a,b,c)
# Error in data.frame(a, b, c) : 
#   arguments imply differing number of rows: 10, 3, 4

better.data.frame(a,b,c)
#             a b c
# 1  2012-02-17 1 a
# 2  2012-02-18 2 b
# 3  2012-02-19 3 c
# 4  2012-02-20 1 d
# 5  2012-02-21 2 a
# 6  2012-02-22 3 b
# 7  2012-02-23 1 c
# 8  2012-02-24 2 d
# 9  2012-02-25 3 a
# 10 2012-02-26 1 b
Run Code Online (Sandbox Code Playgroud)