gpt4 book ai didi

r - 通过函数传递表达式

转载 作者:行者123 更新时间:2023-12-04 12:28:26 30 4
gpt4 key购买 nike

我正在使用 data.table包并尝试编写一个函数(如下所示):

require(data.table)
# Function definition
f = function(path, key) {
table = data.table(read.delim(path, header=TRUE))
e = substitute(key)
setkey(table, e) # <- Error in setkeyv(x, cols, verbose = verbose) : some columns are not in the data.table: e
return(table)
}

# Usage
f("table.csv", ID)

在这里,我尝试将表达式传递给函数。为什么这段代码不起作用?

我已经尝试过 substitute() 的不同组合, quote()eval() .因此,如果您还可以解释如何使其工作,那就太好了。

最佳答案

首先,我们来看看setkey函数执行来自 data.table 的事情包裹:

# setkey function
function (x, ..., verbose = getOption("datatable.verbose"))
{
if (is.character(x))
stop("x may no longer be the character name of the data.table. The possibility was undocumented and has been removed.")
cols = getdots()
if (!length(cols))
cols = colnames(x)
else if (identical(cols, "NULL"))
cols = NULL
setkeyv(x, cols, verbose = verbose)
}

所以,当你这样做时:
require(data.table)
dt <- data.table(ID=c(1,1,2,2,3), y = 1:5)
setkey(dt, ID)

它调用函数 getdots这是内部的 data.table (也就是说,它没有导出)。我们来看看这个函数:
# data.table:::getdots
function ()
{
as.character(match.call(sys.function(-1), call = sys.call(-1),
expand.dots = FALSE)$...)
}

那么,这有什么作用呢?它采用您在 setkey 中输入的参数它使用 match.call分别提取参数。也就是说, match.call这个例子的论点是:
setkey(x = dt, ... = list(ID))

由于它是一个列表,您可以访问 ...参数与 $...获取包含 1 个元素的列表及其值 ID并将此列表转换为带有 as.character 的字符结果 "ID" (字符向量)。然后 setkey将此传递给 setkeyv在内部设置键。

现在为什么当你写 setkey(table, key) 时这不起作用在你的函数里面?

这正是因为方式 setkey/getdots是。 setkey函数被设计为在第一个参数(它是 data.table )之后接受任何参数,然后返回 ...参数作为字符。

也就是说,如果你给 setkey(dt, key)然后它会返回 cols <- "key" .如果你给 setkey(dt, e) ,它会回馈 cols <- "e" .它不会查找“key”是否为现有变量,如果是,则替换变量的值。它所做的只是将您提供的值(无论是符号还是字符)转换回字符。

当然,这在您的情况下不起作用,因为您想要 key 中的值= 要在 setkey 中提供的 ID .至少我想不出办法做到这一点。

如何解决这个问题?

正如@agstudy 已经提到的,最好/最简单的方法是通过 "ID"并使用 setkeyv .但是,如果你真的坚持使用 f("table.csv", ID)那么,这就是你可以做的:
f <- function(path, key) {
table = data.table(read.delim(path, header=TRUE))
e = as.character(match.call(f)$key)
setkeyv(table, e)
return(table)
}

在这里,您首先使用 match.call获取与参数 key 对应的值然后将其转换为 character然后将其传递给 setkeyv .

总之, setkey内部使用 setkeyv .恕我直言,当您已经知道 data.table 的列名时,setkey 是一个很方便的函数。您需要为其设置 key 。希望这可以帮助。

关于r - 通过函数传递表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17036775/

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