[英]Piping histograms in dplyr (R)
是否可以在 dplyr 中通过管道传输多个图形。
这是有效的:
birdsss = data.frame(x1 = 1:10,x2 = 21:30,x3 = 41:50)
birdsss%>%
with(hist(x1, breaks = 50))
但这不起作用:
birdsss%>%
with(hist(x1, breaks = 50)) %>%
with(hist(x2, breaks = 50)) %>%
with(hist(x3, breaks = 50))
Error in hist(x2, breaks = 50) : object 'x2' not found
我也试过:
birdsss%>%
with(hist(x1, breaks = 50)) &
with(hist(x2, breaks = 50)) &
with(hist(x3, breaks = 50))
和
birdsss%>%
with(hist(x1, breaks = 50)) ;
with(hist(x2, breaks = 50)) ;
with(hist(x3, breaks = 50))
在一行中打印多列的解决方案是什么?
类似的东西:
birdsss%>%
with(hist(x1:x3, breaks = 50))
我正在使用更长的管道(filter()、select() 等)以及如何用多个图形完成。 我在这里简化了代码。
lapply
将我上面的一些评论放入答案中,制作每个变量的直方图的最简单方法是
# let's put them in a single plot
par(mfrow = c(1, 3))
lapply(birdsss, hist, breaks = 50) # or chain into it: birdsss %>% lapply(hist, breaks = 50)
# set back to normal
par(mfrow = c(1, 1))
不过,这确实弄乱了标签:
Map
/ mapply
为了用 base 解决这个问题,我们需要并行迭代数据和标签,这可以用Map
或mapply
来完成(因为我们不关心结果——只关心副作用——差异并不重要):
par(mfrow = c(1, 3))
Map(function(x, y){hist(x, breaks = 50, main = y, xlab = y)},
birdsss,
names(birdsss))
par(mfrow = c(1, 1))
漂亮多了。 但是,如果要链接到它,则需要使用.
显示数据应该去哪里:
birdsss %>%
Map(function(x, y){hist(x, breaks = 50, main = y, xlab = y)},
.,
names(.))
Hadley 的purrr
包使*apply
风格的循环更明显地可链接(虽然不相关,但更容易处理列表)而无需担心.
s。 在这里,由于您要迭代副作用并希望迭代两个变量,请使用walk2
:
library(purrr)
walk2(birdsss, names(birdsss), ~hist(.x, breaks = 50, main = .y, xlab = .y))
它返回与前一个Map
调用mfrow
的内容(如果您以相同的方式设置mfrow
),尽管没有无用的输出到控制台。 (如果您需要该信息,请改用map2
。)但请注意,要迭代的参数首先出现,因此您可以轻松链接:
birdsss %>% walk2(names(.), ~hist(.x, breaks = 50, main = .y, xlab = .y))
以完全不同的方式,如果您打算最终将所有内容都放在一个图中,ggplot2 可以通过其facet_*
函数轻松制作相关图:
library(ggplot2)
# gather to long form, so there is a variable of variables to split facets by
birdsss %>%
tidyr::gather(variable, value) %>%
ggplot(aes(value)) +
# it sets bins intead of breaks, so add 1
geom_histogram(bins = 51) +
# make a new "facet" for each value of `variable` (formerly column names), and
# use a convenient x-scale instead of the same for all 3
facet_wrap(~variable, scales = 'free_x')
它看起来有点不同,但一切都是可编辑的。 请注意,您无需任何工作即可获得漂亮的标签。
正常的管道%>%
将左侧管道输送到右侧。 hist
返回一个(非常有用的) hist
对象,但它不是可以通过管道传输到另一个直方图的数据。 你想要“T”管:
library(magrittr)
birdsss %T>%
with(hist(x1, breaks = 50)) %T>%
with(hist(x2, breaks = 50)) %T>%
with(hist(x3, breaks = 50))
这会将第一个“T”之前的任何内容通过管道传输到之后的任何内容。 有关详细信息,请参阅magrittr 文档。
另一种方法:
library(dplyr)
library(tidyr)
birdsss <- data.frame(x1 = 1:10, x2 = 21:30, x3 = 41:50)
my_hist <- function(x) {
hist(x$val, breaks=50, xlab=x$var[1], main=sprintf("Histogram of %s", x$var[1]))
}
par(mfrow=c(3,1))
birdsss %>%
gather(var, val, x1, x2, x3) %>%
group_by(var) %>%
do(a=my_hist(.)) %>%
invisible()
par(mfrow=c(1,1))
你可以试试:
attach(birdsss)
hist(x1,breaks = 50)
hist(x2,breaks = 50)
hist(x3,breaks = 50)
detach(birdsss)
或者可能更好:
with(birdsss,{
hist(x1,breaks = 50)
hist(x2,breaks = 50)
hist(x3,breaks = 50)
}
)
我记得在某处读到使用attach
会导致混乱。
如果您想将其完全保留在dplyr
您只需使用select
函数来选择您希望生成直方图的变量,以使用以下解决方案:
hist((birdsss %>%
select(x1:x3)), breaks = 20)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.