我将如何使用mutate
(我的推测是我在寻找标准评估,因此mutate_
,但我并不完全自信在这一点上)当使用接受变量名称列表的函数时,例如:
createSum = function(data, variableNames) {
data %>%
mutate_(sumvar = interp(~ sum(var, na.rm = TRUE),
var = as.name(paste(as.character(variableNames), collapse =","))))
}
这是一个MWE,它将功能剥离到其核心逻辑并演示我想要实现的目标:
library(dplyr)
library(lazyeval)
# function to make random table with given column names
makeTable = function(colNames, sampleSize) {
liSample = lapply(colNames, function(week) {
sample = rnorm(sampleSize)
})
names(liSample) = as.character(colNames)
return(tbl_df(data.frame(liSample, check.names = FALSE)))
}
# create some sample data with the column name patterns required
weekDates = seq.Date(from = as.Date("2014-01-01"),
to = as.Date("2014-08-01"), by = "week")
dfTest = makeTable(weekDates, 10)
# test mutate on this table
dfTest %>%
mutate_(sumvar = interp(~ sum(var, na.rm = TRUE),
var = as.name(paste(as.character(weekDates), collapse =","))))
此处的预期输出是:
返回的内容rowSums(dfTest[, as.character(weekDates)])
答案 0 :(得分:5)
我认为这就是你所追求的目标
createSum = function(data, variableNames) {
data %>%
mutate_(sumvar = paste(as.character(variableNames), collapse ="+"))
}
createSum(dfTest, weekDates)
我们只提供字符值而不是interp
,因为您无法将名称列表作为单个参数传递给函数。另外,sum()
会执行一些不希望的折叠,因为操作不是按行执行的,而是一次传递给矢量列。
此示例的另一个问题是您在data.frame中设置了check.names=FALSE
,这意味着您创建的列名不能是有效符号。如果您愿意,可以在反向标记中明确包装变量名称
createSum(dfTest , paste0("`", weekDates,"`"))
但一般来说最好不要使用无效名称。
答案 1 :(得分:1)
我不知道这是否是“官方认可的”dplyr
方式,但这是可能的:
weekDates = as.character(weekDates) # more convenient
dfTest %>% mutate(sumvar = Reduce(`+`, lapply(weekDates, get, .)))
#or
dfTest %>% mutate(sumvar = rowSums(as.data.frame(lapply(weekDates, get, .))))
这确实会带来潜在的重大性能损失,具体取决于您的特定用途 - 除dplyr
定期复制整个数据外,我认为它还会在内部计算期间再次复制它。您可以查看data.table
以避免通过添加列来进行额外复制(并使用.SDcols
来避免第二个副本)+您将获得更好的语法。