我目前正在尝试使用预定义的字符串来识别R中的多个列名。更明确地说,我正在使用 ave
函数为数据帧的子组创建标识变量。转折点是我希望标识变量是灵活的,这样我就可以将其作为通用字符串传递。
示例代码为:
ids = with(df,ave(rep(1,nrow(df)),subcolumn1,subcolumn2,subcolumn3,FUN=seq_along))
我想以以下方式运行此代码(下面的代码无法按预期工作(:
subColumnsString = c("subcolumn1","subcolumn2","subcolumn3")
ids = with(df,ave(rep(1,nrow(df)),subColumnsString ,FUN=seq_along))
我尝试了一些 eval,但仍然不起作用:
subColumnsString = c("subcolumn1","subcolumn2","subcolumn3")
ids = with(df,ave(rep(1,nrow(df)),eval(parse(text=subColumnsString)),FUN=seq_along))
有什么想法吗?谢谢。
编辑:我想要的工作代码示例:
df = mtcars
id_names = c("vs","am")
idDF_correct = transform(df,idItem = as.numeric(interaction(vs,am)))
idDF_wrong = cbind(df,ave(rep(1,nrow(df)),df[id_names],FUN=seq_along))
请注意,在idDF_correct中,唯一组合如何正确映射到 idItem 的唯一值。idDF_wrong情况并非如此。
我认为这达到了您的要求。在这里,我使用 R 附带的mtcars
数据集:
subColumnsString <- c("cyl","gear")
ids = with(mtcars, ave(rep(1,nrow(mtcars)), mtcars[subColumnsString], FUN=seq_along))
只需使用子列索引您的数据.帧,该子列返回一个自然适用于ave
的列表
编辑
ids = ave(rep(1,nrow(mtcars)), mtcars[subColumnsString], FUN=seq_along)
你可以省略with
,只称普通的ave
,正如G. Grothendieck所说,你也应该使用他们的答案,因为它更笼统。
这定义了一个函数,其参数为:
-
data
,输入数据框 -
by
,列名的字符向量data
-
fun
,一个用于ave
的函数
法典--
Ave <- function(data, by, fun = seq_along) {
do.call(function(...) ave(rep(1, nrow(data)), ..., FUN = fun), data[by])
}
# test
Ave(CO2, c("Plant", "Treatment"), seq_along)
给:
[1] 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3
[39] 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6
[77] 7 1 2 3 4 5 6 7