具有外部数据的dplyr突变

时间:2018-08-06 12:21:24

标签: r dplyr tidyverse

我们可以轻松地对分类方式进行变异/总结:

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)

enter image description here

但是请考虑以下情况,例如,其他一些基线(即,等同于但不同于以上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本身或对其进行克隆?

1 个答案:

答案 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