R 将负值替换为上一行/2

R 将负值替换为上一行/2,r,dplyr,R,Dplyr,我想调整val列,这样就不会有任何负值 调整规则是 将负值替换为上一行的一半 为每个hier(分组人(hier))执行此操作 如果连续出现多个负值,则将以前的调整值除以2 xdat <- data.frame( hier = c(rep("A",5), rep("B",5) ) , val = c(4, 7, -3, 10, 5, 1, -7, -4, 5, 7) ) hier | val | val_adjust A | 4 | 4

我想调整val列,这样就不会有任何负值

调整规则是

  • 将负值替换为上一行的一半
  • 为每个hier(分组人(hier))执行此操作
  • 如果连续出现多个负值,则将以前的调整值除以2

    xdat <- data.frame( 
      hier = c(rep("A",5), rep("B",5) )
      , val = c(4, 7, -3, 10, 5, 1, -7, -4, 5, 7)
               )
    
    hier |  val | val_adjust
    A    |  4   |    4
    A    |  7   |    7
    A    |  -3  |    3.5
    A    |  10  |    10
    A    |  5   |    5
    B    |  1   |    1
    B    |  -7  |    0.5
    B    |  -4  |    0.25
    B    |  5   |    5
    B    |  7   |    7
    

    xdat在生成可重复的问题时找到了答案

    xdat %>% 
      rowid_to_column("rowid") %>% 
      group_by(hier) %>% 
      mutate(rowid = rank(rowid)) %>% 
      mutate(val_adj1 = lag(val)) %>% 
      mutate(val_adj1 = case_when(val < 0~val_adj1/2, TRUE~val)) %>% 
      mutate(val_adj2 = lag(val_adj1)) %>% 
      mutate(val_adj2 = case_when(val_adj1 < 0~val_adj2/2, TRUE~val_adj1))  
    
    xdat%>%
    rowid_至_列(“rowid”)%%>%
    分组依据(hier)%>%
    变异(rowid=rank(rowid))%>%
    突变(val_adj1=滞后(val))%>%
    当(val<0~val\u adj1/2,TRUE~val))%>
    突变(val_adj2=滞后(val_adj1))%>%
    变异(val_adj2=情况(val_adj1<0~val_adj2/2,TRUE~val_adj1))
    
    产生

       rowid   hier   val val_adj1 val_adj2
       <dbl> <fctr> <dbl>    <dbl>    <dbl>
     1     1      A     4      4.0     4.00
     2     2      A     7      7.0     7.00
     3     3      A    -3      3.5     3.50
     4     4      A    10     10.0    10.00
     5     5      A     5      5.0     5.00
     6     1      B     1      1.0     1.00
     7     2      B    -7      0.5     0.50
     8     3      B    -4     -3.5     0.25
     9     4      B     5      5.0     5.00
    10     5      B     7      7.0     7.00
    
    rowid hier val val\u adj1 val\u adj2
    1 1 A 4 4.0 4.00
    2 A 7.0 7.00
    3 A-3.5 3.50
    4 4 A 10 10.0 10.00
    5 A 5.0 5.00
    61B11.01.00
    7 2 B-7 0.5 0.50
    8b-4-3.50.25
    9 4 B 5 5.0 5.00
    105B7.077.00
    
    在生成可重复的问题时找到了答案

    xdat %>% 
      rowid_to_column("rowid") %>% 
      group_by(hier) %>% 
      mutate(rowid = rank(rowid)) %>% 
      mutate(val_adj1 = lag(val)) %>% 
      mutate(val_adj1 = case_when(val < 0~val_adj1/2, TRUE~val)) %>% 
      mutate(val_adj2 = lag(val_adj1)) %>% 
      mutate(val_adj2 = case_when(val_adj1 < 0~val_adj2/2, TRUE~val_adj1))  
    
    xdat%>%
    rowid_至_列(“rowid”)%%>%
    分组依据(hier)%>%
    变异(rowid=rank(rowid))%>%
    突变(val_adj1=滞后(val))%>%
    当(val<0~val\u adj1/2,TRUE~val))%>
    突变(val_adj2=滞后(val_adj1))%>%
    变异(val_adj2=情况(val_adj1<0~val_adj2/2,TRUE~val_adj1))
    
    产生

       rowid   hier   val val_adj1 val_adj2
       <dbl> <fctr> <dbl>    <dbl>    <dbl>
     1     1      A     4      4.0     4.00
     2     2      A     7      7.0     7.00
     3     3      A    -3      3.5     3.50
     4     4      A    10     10.0    10.00
     5     5      A     5      5.0     5.00
     6     1      B     1      1.0     1.00
     7     2      B    -7      0.5     0.50
     8     3      B    -4     -3.5     0.25
     9     4      B     5      5.0     5.00
    10     5      B     7      7.0     7.00
    
    rowid hier val val\u adj1 val\u adj2
    1 1 A 4 4.0 4.00
    2 A 7.0 7.00
    3 A-3.5 3.50
    4 4 A 10 10.0 10.00
    5 A 5.0 5.00
    61B11.01.00
    7 2 B-7 0.5 0.50
    8b-4-3.50.25
    9 4 B 5 5.0 5.00
    105B7.077.00
    
    您可以从
    purrr

    library(tidyverse)
     xdat%>%group_by(hier)%>%mutate(adj_val=accumulate(val,~ifelse(.y<0,.x/2,.y)))
    # A tibble: 10 x 3
    # Groups:   hier [2]
         hier   val adj_val
       <fctr> <dbl>   <dbl>
     1      A     4    4.00
     2      A     7    7.00
     3      A    -3    3.50
     4      A    10   10.00
     5      A     5    5.00
     6      B     1    1.00
     7      B    -7    0.50
     8      B    -4    0.25
     9      B     5    5.00
    10      B     7    7.00
    
    库(tidyverse)
    
    xdat%%>%group\U by(hier)%%>%mutate(adj\U val=累积(val,~ifelse(.y您可以使用
    累积
    from
    purrr

    library(tidyverse)
     xdat%>%group_by(hier)%>%mutate(adj_val=accumulate(val,~ifelse(.y<0,.x/2,.y)))
    # A tibble: 10 x 3
    # Groups:   hier [2]
         hier   val adj_val
       <fctr> <dbl>   <dbl>
     1      A     4    4.00
     2      A     7    7.00
     3      A    -3    3.50
     4      A    10   10.00
     5      A     5    5.00
     6      B     1    1.00
     7      B    -7    0.50
     8      B    -4    0.25
     9      B     5    5.00
    10      B     7    7.00
    
    库(tidyverse)
    
    xdat%%>%group_by(hier)%%>%mutate(调整值=累积值,~ifelse(.Y如果hier中的第一个值为负怎么办?在我的情况下不会,但我的建议是将最低值的一半写在$val2上,如果hier中的第一个值为负怎么办?在我的情况下不会,但我的建议是将最低值的一半写在$val2上,你的建议可能是最优雅的方法做这件事,thanksI会采取dplyr的方式:)@onyanbuddn不知道积累,你的建议可能是做这件事最优雅的方式,thanksI会采取dplyr的方式:)@onyanbu