如何用magrittr的Tee管道%T>%为R分组数据生成多幅ggplot
我想要为每组数据创建直方图,然后返回汇总结果。我尝试用大括号和print函数配合Tee管道来避免绘图后中断后续操作,但这种方式没法识别分组:
data(mtcars) mtcars |> group_by(cyl) %T>% {print(ggplot(.) + geom_histogram(aes(x = carb)))} |> summarise(meancarb = mean(carb))
这段代码只会生成单幅直方图,同时返回汇总结果。而执行下面这段代码时:
mtcars %T>% {print(ggplot(.) + geom_histogram(aes(x = carb)))} |> group_by(cyl) |> summarise(meancarb = mean(carb))
输出完全一样,这说明group_by根本没起作用。
有没有人知道为什么分组没被用来为每个唯一的cyl值生成单独的直方图?我想学会更熟练地用Tee管道做这类操作,包括把输出保存成唯一名称后继续主管道的操作。感觉Tee管道的资料很少,没被充分利用,如果有人能分享实用示例,对社区会很有帮助。
谢谢!
根据建议用dplyr::group_map(或group_walk),我试了这段代码:
mtcars |> group_by(cyl) %T>% group_walk(.f = ~ ggplot(.) + geom_histogram(aes(x = carb))) |> summarise(meancarb = mean(carb, na.rm = TRUE), sd3 = sd(carb, na.rm = TRUE) * 3)
这段代码生成了汇总表,但没出任何图。不管用map还是walk,把%T>%换成|>结果都一样,感觉group_walk和%T>%的作用差不多。用|>加group_map时,还碰到了错误:
Error in UseMethod("summarise"): no applicable method for 'summarise' applied to an object of class "list"
尝试加print和大括号:
mtcars |> group_by(cyl) %T>% {print(group_walk(.f = ~ ggplot(.) + geom_histogram(aes(x = carb))))} |> summarise(meancarb = mean(carb, na.rm = TRUE), sd3 = sd(carb, na.rm = TRUE) * 3)
又出现错误:
Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'print': argument ".data" is missing, with no default
只加{}不加print时:
Error in group_map(.data, .f, ..., .keep = .keep): argument ".data" is missing, with no default
只加print不加{}时,错误和只加{}的情况一样。
感谢思路,下面这段代码能正常运行,为每组生成一幅图:
mtcars |> group_split(cyl) |> map(.f = ~ ggplot(.) + geom_histogram(aes(x = carb)))
但我找不到合适的Tee/管道组合,既能把mtcars分流到group_split和map生成图,又能回到主管道继续操作:
mtcars %T>% group_split(cyl) %T>% map(.f = ~ ggplot(.) + geom_histogram(aes(x = carb))) |> summarise(meancarb = mean(carb))
出现错误:
Error in
map(): In index: 1. With name: mpg. Caused by error infortify():datamust be a <data.frame>, or an object coercible byfortify(), not a double vector.
而且只有用两个Tee管道时才会生成图。
我试着调整管道顺序(但这种方法不是总能适用或符合需求):
mtcars |> group_by(cyl) %T>% summarise(meancarb = mean(carb)) |> ungroup() |> group_split(cyl) |> map(.f = ~ ggplot(.) + geom_histogram(aes(x = carb)))
这段代码生成了3幅图,但没打印汇总结果。在汇总语句周围加{}和/或print会出现错误:
Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'mean': object 'carb' not found.
有没有人知道Tee管道是不是只能用于单个命令?就是说没法在分流分支上继续执行管道命令后再回到主管道?感谢大家!
感谢解答。后续问题:怎么在不用公式格式首个命令的情况下实现多命令Tee管道?
下面这段代码能正常运行,打印单个数值:
mtcars |> summarise(sdd = sd(carb, na.rm = TRUE))
但下面这段代码不会打印数值,只会执行计算后继续后续操作:
mtcars %T>% summarise(sdd = sd(carb, na.rm = TRUE)) |> summarise( meancarb = mean(carb, na.rm = TRUE), sd3 = sd(carb, na.rm = TRUE) * 3 )
我试了各种print和{}的组合,都会出现以下错误:
Error: function '{' not supported in RHS call of a pipe
或者:
Error in is.data.frame(x) : object 'carb' not found
比如我想实现类似这样的操作:
mtcars |> summarise(~{ print(sdd = sd(carb)) write_csv(file = "tmp.csv") .x }) |> summarise(meancarb = mean(carb))
有什么办法吗?再次感谢!
内容的提问来源于stack exchange,提问作者dez93_2000

