【发布时间】:2021-10-14 01:57:32
【问题描述】:
data.table 和 ggplot 经常遇到的一个问题是它们在 for 循环中的使用,我在其中迭代一组列名。
以这张数据表为例:
dt <- data.table(values1=rep(c(1,2),each=2),
values2=rep(c(10,20),each=2),
notthis=0,
category=rep(c('a','b'),each=2))
##
## values1 values2 notthis category
## 1: 1 10 0 a
## 2: 1 10 0 a
## 3: 2 20 0 b
## 4: 2 20 0 b
假设我想遍历dt 的所有列,除了notthis 和category。对于每一列,我想根据category绘制其值的两个直方图,并添加一条表示它们的平均值的垂直线(可能使用pdf、print、dev.off将这些图传递到pdf设备) .
代码思路可以如下:
loopnames <- setdiff(colnames(dt), c('notthis', 'category'))
## [1] "values1" "values2"
for(ZZZ in loopnames){
dtmeans <- dt[, .(means=mean(ZZZ)), by=category]
ggplot(dt) + geom_histogram(aes(x=ZZZ, fill=category)) +
geom_vline(data=dtmeans, aes(xintercept=means, color=category))
}
但显然它不起作用。使用ZZZ 变量会在data.table 和ggplot 中产生错误。
注意某些代码行背后的原因:
- 我想构建一个列列表进行迭代,由差异定义:
dt可能有数百列,我只想排除其中两个列。 - 我需要构建一个数据表,其中包含传递给
geom_vline的方法(在我看来,这个数据表是多余的,但这是ggplot想要的)。 - 我想使用
data.table的特殊语法来构造这样的数据表。
参考this post、this post 和this post 的有用答案,我尝试了各种组合以使上述代码理念发挥作用:使用with=FALSE 作为数据表,quote()/ eval() 对,“取消引用”!! 字符,以及 as.names() 和 sym()。但没有任何组合奏效。最接近解决问题的是 quote()/eval() 对,它似乎对 data.table 和 ggplot 都有效,但我没有设法在 for 循环中使用此解决方法。
您能否建议一种通用方法不使用 tidyverse 命令来处理包中的变量/循环列名,例如 data.table 和 ggplot?
【问题讨论】:
标签: r for-loop ggplot2 data.table