gpt4 book ai didi

r - 防止强制转换为 unlist() 或 c() 中的单一类型;将参数传递给包装函数

转载 作者:行者123 更新时间:2023-12-04 11:49:09 25 4
gpt4 key购买 nike

有没有一种简单的方法可以在保留列表成分的原始类型的同时展平列表?..有没有办法以编程方式从不同的成分类型构建展平的列表?..

例如,我想为像 png(filename,width,height) 这样的函数创建一个简单的包装器,它需要设备名、文件名和选项列表。天真的方法就像

my.wrapper <- function(dev,name,opts) { do.call(dev,c(filename=name,opts)) }

或与 unlist(list(...)) 类似的代码。这是行不通的,因为 opts 被强制转换为字符,结果调用是例如png(文件名,width="500",height="500")

如果没有直接的方法来创建这样的异构列表,是否有一种标准的惯用方法可以将参数拼接成函数而不显式命名它们(例如 do.call(dev,list(filename=name,width=opts [“宽度”]))?

-- 编辑--

Gavin Simpson 在他关于构造包装函数的讨论中回答了以下两个问题。让我总结一下标题问题的答案:

可以用 c() 构造一个列表,前提是至少 c() 的参数之一是一个列表。即:

> foo <- c("a","b"); bar <- 1:3
> c(foo,bar)
[1] "a" "b" "1" "2" "3"
> typeof(c(foo,bar))
[1] "character" ## note that the result is not a list and that coercion occurred
> c(list(foo),list(bar)) ## try also c(foo,list(bar))
[[1]] [1] "a" "b"
[[2]] [1] 1 2 3
> typeof(c(foo,list(bar)))
[1] "list" ## now the result is a list, so no need to coerce to same type
> c(as.list(foo),as.list(bar)) ## this creates a flattened list, as desired
[[1]] [1] "a"
[[2]] [1] "b"
[[3]] [1] 1
[[4]] [1] 2
[[5]] [1] 3

最佳答案

不,因为 unlistc(当应用于不同类型的原子 vectors 时)正在创建一个原子 vector 并且根据定义它们必须是单一类型。 R 中的列表是最通用的向量,您可以使用它,实际上是 do.call asks"args" 参数一个列表,您正在提供一个原子向量(通过使用 c() )。

为什么要使用 do.call 只是生成一个新设备?如果你想要的只是一个 png 的包装器,它设置了一些默认值,这样你就不必在每次使用 png 设备时都输入所有这些,那么你太复杂了。这样的东西就足够了:

my.png <- function(name, height = 500, width = 500, ...) {
png(filename = name, height = height, width = width, ...)
}

如果你想要一个更通用的包装器,那么像这样:

my.wrapper <- function(dev, name, ...) {
dev(filename = name, ...)
}

应该够了。你会像这样使用它:

my.wrapper(png, "my_png.png", height = 500, width = 200, pointsize = 12)

my.wrapper(pdf, "my_pdf.pdf", height = 8, width = 6, version = "1.4")

如果你想使用 ...,你可以,例如:

my.wrapper2 <- function(dev, name, ...) {
dotargs <- list(...)
writeLines("my.wrapper2, called with the following extra arguments:")
print(dotargs)
## do nothing now...
}

给出:

> my.wrapper2(pdf, "foo.pdf", height = 10, width = 5, pointsize = 8, 
+ version = "1.3")
my.wrapper2, called with the following extra arguments:
$height
[1] 10

$width
[1] 5

$pointsize
[1] 8

$version
[1] "1.3"

然后您可以通过编程方式提取您想要的参数以及您想要的参数。

我刚刚想到的其他可能有用的事情是您可以使用 c 将额外的组件连接到列表中:

> c(filename = "name", list(height = 500, width = 500))
$filename
[1] "name"

$height
[1] 500

$width
[1] 500

所以如果你真的想将 do.call 应用于一组参数,那么

my.wrapper3 <- function(dev, name, ...) {
dotargs <- list(...)
## concatenate with name
callArgs <- c(filename = name, dotargs)
## use do.call
do.call(dev, args = callArgs)
}

但是使用上面的 my.wrapper 可以更轻松地实现这一点。

关于r - 防止强制转换为 unlist() 或 c() 中的单一类型;将参数传递给包装函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4624701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com