代码之家  ›  专栏  ›  技术社区  ›  geotheory

外部数据的dplyr突变

  •  0
  • geotheory  · 技术社区  · 8 年前

    我们可以很容易地对分类方法进行变异/总结:

    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 回复  |  直到 8 年前
        1
  •  3
  •   moodymudskipper    8 年前

    可以在相关列上循环 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
    

    为了便于将来使用,您可以使用以下函数(用base编写 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