R 避免将函数参数包装在“中”;引号();在函数中使用data.table时
我有一个函数,R 避免将函数参数包装在“中”;引号();在函数中使用data.table时,r,data.table,R,Data.table,我有一个函数,create.summary,当传递一个列名时,它会按年份和月份汇总该列的值。注意在数据表的j表达式中使用了eval() create.summary <- function(full.panel.df, outcome.name){ df.apps <- data.table(full.panel.df)[, list( Y = mean(eval(outcome.name)),
create.summary
,当传递一个列名时,它会按年份和月份汇总该列的值。注意在数据表的j
表达式中使用了eval()
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(eval(outcome.name)),
se = sd(eval(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary尝试使用get
而不是eval
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary尝试使用get
而不是eval
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary为了我(希望还有其他人)的缘故,我已经根据不同的行为排列了我的答案和@GSee、@BrodieG的答案。至少我觉得这个比较有用
对于:create.summary(df,小时收入)
- 将
eval
更改为evalq
,在这种情况下显然是最简单的
从帮助文件:
evalq表单相当于eval(quote(expr),…)。eval在将其传递给计算器之前,先计算当前作用域中的第一个参数:evalq避免了这种情况
您的功能变为:
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(evalq(outcome.name)),
se = sd(evalq(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(eval(parse(text=outcome.name))),
se = sd(eval(parse(text=outcome.name)))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
对于:create.summary(df,“小时收入”)
get()
搜索该名称的对象;它比parse(text=)
您的功能变为:
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(evalq(outcome.name)),
se = sd(evalq(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(eval(parse(text=outcome.name))),
se = sd(eval(parse(text=outcome.name)))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
为了我(希望还有其他人)的缘故,我已经根据不同的行为排列了我的答案和@GSee,@BrodieG的答案。至少我觉得这个比较有用
对于:create.summary(df,小时收入)
- 将
eval
更改为evalq
,在这种情况下显然是最简单的
从帮助文件:
evalq表单相当于eval(quote(expr),…)。eval在将其传递给计算器之前,先计算当前作用域中的第一个参数:evalq避免了这种情况
您的功能变为:
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(evalq(outcome.name)),
se = sd(evalq(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(eval(parse(text=outcome.name))),
se = sd(eval(parse(text=outcome.name)))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
对于:create.summary(df,“小时收入”)
get()
搜索该名称的对象;它比parse(text=)
您的功能变为:
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(evalq(outcome.name)),
se = sd(evalq(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(outcome.name)),
se = sd(get(outcome.name))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
create.summary <- function(full.panel.df, outcome.name){
df.apps <- data.table(full.panel.df)[, list(
Y = mean(eval(parse(text=outcome.name))),
se = sd(eval(parse(text=outcome.name)))/sqrt(.N)
),
by = list(month, year, trt)]
return df.apps
}
和另一个使用替换和获取:
create.summary <- function(full.panel.df, outcome.name){
out.name.quoted <- as.character(substitute(outcome.name))
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(out.name.quoted)),
se = sd(get(out.name.quoted))/sqrt(.N)
),
by = list(month, year, trt)
]
df.apps
}
有了一些数据:
df <- data.frame(month=month.abb, year=rep(2000:2005, each=24), trt=c("one", "two"), a=runif(6 * 12), b=runif(6 * 12))
df和另一个使用substitute
和get
:
create.summary <- function(full.panel.df, outcome.name){
out.name.quoted <- as.character(substitute(outcome.name))
df.apps <- data.table(full.panel.df)[, list(
Y = mean(get(out.name.quoted)),
se = sd(get(out.name.quoted))/sqrt(.N)
),
by = list(month, year, trt)
]
df.apps
}
有了一些数据:
df <- data.frame(month=month.abb, year=rep(2000:2005, each=24), trt=c("one", "two"), a=runif(6 * 12), b=runif(6 * 12))
df如果您有一个名为“system(rm-rf./)”的列会怎么样?@GSee oy。这会很糟糕。我从未想过这一点(实际上我不知道get()
(因此+1).我正试图更好地了解R中的非标准评估任何我可以指向的资源?ps.我应该删除这个答案吗?我不认为这对于用户在自己的终端上以自己的权限运行的函数来说有什么大不了的,这通常是大多数R包的情况。毕竟,他们可以只键入“炸毁我自己系统的命令”,而不是将其传递给第三方函数。如果您从web捕获输入,然后在您的服务器上运行它,则情况就不同了。如果您有一个名为“system(rm-rf./)”的专栏会怎么样?@GSee oy。这将很糟糕。我从未想过这一点(实际上我不知道get()
(因此+1).我正试图更好地了解R中的非标准评估任何我可以指向的资源?ps.我应该删除这个答案吗?我不认为这对于用户在自己的终端上以自己的权限运行的函数来说有什么大不了的,这通常是大多数R包的情况。他们毕竟可以键入“命令“炸毁我自己的系统”,而不是将其传递给第三方函数。如果您从web捕获输入,然后在服务器上运行它,则情况就不同了。好的,除了OP说“我希望用户能够以字符串形式调用此函数:create.summary(df,“hourly_-earning”)“@GSee,我认为OP所说的是相对于quote
变量名的需要而言的(也就是说,使用“var.name”比quote(var.name)
)更可取)。对于OP的“var.name”这一点我并不清楚。”显然优于var.name
。后者是许多用户在使用subset
等时所熟悉的,因此它似乎是一种合理的替代方法。我不认为这优于字符版本。好的,除了OP说“我希望用户能够使用列名作为字符串调用此函数:create.summary(df,“hourly_-earnings”)”@GSee,我认为OP所说的是相对于变量名的需要而言的(也就是说,使用“var.name”比使用quote(var.name)
)对我来说,“var.name”明显优于var.name
。后者是许多用户在使用子集
等时所熟悉的,因此它似乎是一种合理的替代方法。我不认为这比字符版本更优越。