我有一个数据框,其中包含一组对象df$data和一组要应用于每个对象的规则df$rules.
df <- data.frame(
data = c(1,2,3),
rules = c("rule1", "rule1, rule2, rule3", "rule3, rule2"),
stringsAsFactors = FALSE
)
Run Code Online (Sandbox Code Playgroud)
规则是
rule1 <- function(data) {
data * 2
}
rule2 <- function(data) {
data + 1
}
rule3 <- function(data) {
data ^ 3
}
Run Code Online (Sandbox Code Playgroud)
对于数据框中的每一行,我想应用rules列中指定的所有规则.规则应该串联应用.
我想通了什么:
apply_rules <- function(data, rules) {
for (i in 1:length(data)) {
rules_now <- unlist(strsplit(rules[i], ", "))
for (j in 1:length(rules_now)) {
data[i] <- apply_rule(data[i], rules_now[j])
}
}
return(data)
}
apply_rule <- function(data, rule) {
return(sapply(data, rule))
}
apply_rules(df$data, df$rules)
# [1] 2 125 28
Run Code Online (Sandbox Code Playgroud)
虽然这有效但我非常肯定必须有更优雅的解决方案.在SO上我可以找到很多关于apply-functions 的东西,还有一篇关于将很多函数应用于向量和关于链接函数的帖子.这个想法看起来很有希望,但我无法弄清楚如何使用我的规则作为字符串进行调用.(没用......)ComposeComposeparse()
任何提示?
已经有了一些很好的答案,但提出了另一个选择 - 将管道链构建为字符串,然后对其进行评估。例如 - 对于第 1 行 -eval(parse(text = "1 %>% rule1"))给出 2
eval_chain <- function(df) {
eval(parse(text = paste(c(df$data, unlist(strsplit(df$rules, ", "))), collapse=" %>% ")))
}
df$value <- sapply(1:nrow(df), function(i) df[i, ] %>% eval_chain)
# data rules value
# 1 1 rule1 2
# 2 2 rule1, rule2, rule3 125
# 3 3 rule3, rule2 28
Run Code Online (Sandbox Code Playgroud)