让我有这样的数据框:
df <- structure(list(subjecttaxnoid = c("22661187010", "10346575807",
"22439110996", "63510438612", "85267957976", "40178118040", "51246665873",
"66803849969", "45813719599", "26979059418", "11240408751"),
reportyear = c(2014L, 2014L, 2014L, 2008L, 2008L, 2008L,
2008L, 2013L, 2013L, 2013L, 2013L), b001 = c(0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0), b002 = c(0, 3.43884233571018e-07, 7.24705810574303e-08,
1.41222784374111e-07, 1.62917712565032e-05, 0, 4.53310814208705e-07,
7.63856039195011e-06, 0, 0, 0)), .Names = c("subjecttaxnoid",
"reportyear", "b001", "b002"), row.names = c(1L, 2L, 3L, 200000L,
200001L, 200002L, 200003L, 40000L, 40001L, 40002L, 40003L), class = "data.frame")
和包含两列df名称的向量:
x <- c("b001", "b002")
我想在dplyr中使用x的组件而不是列名:
my_list <- list()
for (i in 1:length(x)){
my_list[[1]] <- df %>% group_by(reportyear) %>% top_n(2, wt = x[1])
}
这会返回错误:
Error in eval(substitute(expr), envir, enclos) :
Unsupported use of matrix or array for column indexing
你能帮忙解决这个问题吗?
答案 0 :(得分:1)
除非您想要更改函数x[1]
,否则我认为有一种简单的解决方法(例如,将as.name
包裹在top_n
内)。 @ulfelder在评论中建议的原因是dplyr
使用非标准评估,因此在这种情况下它需要一个不带引号的变量名。其他函数具有处理引用参数的版本(例如mutate_
,rename_
等)但在这种情况下不是。
最简单的方法是使用临时分配,例如
df %>%
group_by(reportyear) %>%
mutate_(tempvar = x[1]) %>%
top_n(2, wt = tempvar) %>%
select(-tempvar)
(当然你需要确保tempvar
不是数据框中已有的变量名,否则它将覆盖现有变量。远离理想状态,您可能已经考虑过并拒绝了它。< / p>
另一种方法是定义自己的top_n_
函数,类似于top_n
,但需要wt
参数中的字符串:
top_n_ <- function (x, n, wt) {
wt <- as.name(wt)
stopifnot(is.numeric(n), length(n) == 1)
if (n > 0) {
call <- substitute(filter(x, min_rank(desc(wt)) <= n),
list(n = n, wt = wt))
}
else {
call <- substitute(filter(x, min_rank(wt) <= n), list(n = abs(n),
wt = wt))
}
eval(call)
}
这基本上只是在函数定义的顶部使用top_n
并更改wt
参数的处理。然后就可以了
df %>% group_by(reportyear) %>% top_n_(2, wt = x[1])
identical(
df %>% group_by(reportyear) %>% top_n_(2, wt = x[1]),
df %>% group_by(reportyear) %>% top_n(2, wt = b001),
)
# TRUE
identical(
df %>% group_by(reportyear) %>% top_n_(2, wt = x[2]),
df %>% group_by(reportyear) %>% top_n(2, wt = b002),
)
# TRUE