【问题标题】:How to subtract even row numbers with odd row numbers across columns using dplyr in R如何使用R中的dplyr在列中减去奇数行数的偶数行数
【发布时间】:2021-07-06 12:56:37
【问题描述】:

我的数据框是这样的

df <-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), time=rep(c("0h","72h"),2))
  col1 col2 time
1    1    5   0h
2    2    6  72h
3    3    7   0h
4    4    8  72h

我想使用 mutate_across 或任何其他 dplyr 函数(最好)从每列的前一行中减去 72h 的值和 0h 的值。

我希望我的数据看起来像这样

  col1 col2 time
     1    1   72h
     1    1   72h

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    基础

    df <-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), time=rep(c(0,72),2))
    
    df[c(FALSE,TRUE), ] - df[c(TRUE, FALSE), ]
    #>   col1 col2 time
    #> 2    1    1   72
    #> 4    1    1   72
    

    由reprex package (v2.0.0) 于 2021-07-06 创建

    tidyverse 使用@Emir Dakin 的方法

    library(tidyverse)
    df <-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), time=rep(c("0h", "72h"),2))
    
    df %>%
      mutate(across(where(is.numeric), ~.x - lag(.x, default = first(.x)))) %>%
      filter(time == "72h")
    #>   col1 col2 time
    #> 1    1    1  72h
    #> 2    1    1  72h
    

    由reprex package (v2.0.0) 于 2021-07-06 创建

    【讨论】:

      【解决方案2】:

      如果数据按您显示的那样整齐排列,您可以使用lag 函数。这是一个非常简单的应用程序,但它应该可以工作,我认为除了mutate之外你不需要其他任何东西:

      df %>%
        mutate(col1 = col1 - lag(col1, default = first(col1)),
               col2 = col2 - lag(col2, default = first(col2))) %>%
        filter(time == "72h")
      

      【讨论】:

      • 谢谢埃米尔。 Atm 我有多个列,我将尝试看看它是如何与 mutate_across() 一起工作的。感谢您的宝贵时间
      • df %&gt;% mutate(across(where(is.numeric), ~.x - lag(.x, default = first(.x)))) %&gt;% filter(time == "72h")
      【解决方案3】:

      根据 Emir Dakin 的回答,我添加了一个带有时间发生顺序的控件:

      library(dplyr)
      df %>% group_by(time) %>% mutate(sl= seq(time)) %>% group_by(sl) %>% 
        mutate(col1 = col1 - lag(col1, default = first(col1), order_by = time), 
               col2 = col2 - lag(col2, default = first(col2), order_by = time))  %>% 
        ungroup() %>% filter(time  == "72h") %>% select(col1, col2, time) 
      
      # A tibble: 2 x 3
         col1  col2 time 
        <dbl> <dbl> <chr>
      1     1     1 72h  
      2     1     1 72h  
      

      【讨论】:

        【解决方案4】:

        或者:

        library(tidyverse)
        
        df <-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), time=rep(c("0h","72h"),2))
        
        df %>%
          mutate(id = rep(seq(nrow(df) / 2), each = 2), # create an id of what belongs together
                 tmp = rep(c("start", "end"), nrow(df) / 2),
                 time = as.numeric(str_remove(time, "h"))) %>%
          mutate_at(vars("col1":"time"), ~if_else(tmp == "start", .x * -1, .x)) %>%
          group_by(id) %>%
          summarise_at(vars("col1":"time"), sum) 
        
        # # A tibble: 2 x 4
        # id  col1  col2  time
        # <int> <dbl> <dbl> <dbl>
        # 1     1     1     1    72
        # 2     2     1     1    72
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多