我们可以轻松地对分类方式进行变异/总结:
require(tidyverse)
iris %>% mutate_if(is.double, funs(. - mean(.))) %>%
gather(dimension, value, -Species) %>%
group_by(Species, dimension) %>% summarise(value = mean(value)) %>%
ggplot(aes(dimension, value, fill=value)) + geom_bar(stat='identity') +
coord_flip() + facet_wrap(~ Species)
但是请考虑以下情况,例如,其他一些基线(即,等同于但不同于以上mutate_if
中调用的平均值) >
baseline = data_frame(Sepal.Length=3, Sepal.Width=2, Petal.Length=2, Petal.Width=1)
要整合这些内容,一种简单的base-r方法很简单,但并不优雅:
for(i in 1:4) iris[,i] = iris[,i] - as.numeric(baseline[,i])
但是我想知道是否有更好的整洁的方式将baseline
并入管道中-即避免必须更改iris
本身或对其进行克隆?
答案 0 :(得分:3)
您可以使用purrr::imap
library(purrr)
iris %>% imap_dfc(~if(.y %in% names(baseline)) .x-baseline[[.y]] else .x)
# # A tibble: 150 x 5
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# <dbl> <dbl> <dbl> <dbl> <fctr>
# 1 2.1 1.5 -0.6 -0.8 setosa
# 2 1.9 1.0 -0.6 -0.8 setosa
# 3 1.7 1.2 -0.7 -0.8 setosa
# 4 1.6 1.1 -0.5 -0.8 setosa
# 5 2.0 1.6 -0.6 -0.8 setosa
# 6 2.4 1.9 -0.3 -0.6 setosa
# 7 1.6 1.4 -0.6 -0.7 setosa
# 8 2.0 1.4 -0.5 -0.8 setosa
# 9 1.4 0.9 -0.6 -0.8 setosa
# 10 1.9 1.1 -0.5 -0.9 setosa
为便于将来使用,您可以使用以下函数(以R
为基础编写),我对该函数进行了概括,因此您不仅限于减法。 .baseline
也可以是列表或命名向量。
baseline_op <- function(.x, .baseline, .f = `-`, ...) {
.x[names(.baseline)] <- lapply(names(.baseline),function(n, ...) .f(.x[[n]], .baseline[[n]], ...))
.x
}
iris %>% baseline_op(baseline) %>% head
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 2.1 1.5 -0.6 -0.8 setosa
# 2 1.9 1.0 -0.6 -0.8 setosa
# 3 1.7 1.2 -0.7 -0.8 setosa
# 4 1.6 1.1 -0.5 -0.8 setosa
# 5 2.0 1.6 -0.6 -0.8 setosa
# 6 2.4 1.9 -0.3 -0.6 setosa
iris %>% baseline_op(baseline, pmax, na.rm = TRUE) %>% head
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 2 1 setosa
# 2 4.9 3.0 2 1 setosa
# 3 4.7 3.2 2 1 setosa
# 4 4.6 3.1 2 1 setosa
# 5 5.0 3.6 2 1 setosa
# 6 5.4 3.9 2 1 setosa