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

条件子代数

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

    我有这样的数据框

    test <- data.frame(gr=rep(letters[1:2],each=6),No=c(100:105,200:205))
    
       gr  No
    1   a 100
    2   a 101
    3   a 102
    4   a 103
    5   a 104
    6   a 105
    7   b 200
    8   b 201
    9   b 202
    10  b 203
    11  b 204
    12  b 205
    

    No 每列的数字都在增加 gr 是的。我需要总结一下 gr a 用100和 b 有50个,手术后需要连续下降。

    我想有一个新的专栏,随着这个增加而连续减少。所以我试着

    decrese_func <- function(No,gr){
    
       if(any(gr=="a")){
         No+100
    
       }
       else
        No+50 
     }
    
       test%>%
       group_by(gr)%>%
       mutate(new_column=decrese_func(No,gr))
    
    # A tibble: 12 x 3
    # Groups:   gr [2]
       gr       No new_column
       <fct> <int>      <dbl>
     1 a       100        200
     2 a       101        201
     3 a       102        202
     4 a       103        203
     5 a       104        204
     6 a       105        205
     7 b       200        250
     8 b       201        251
     9 b       202        252
    10 b       203        253
    11 b       204        254
    12 b       205        255
    

    但我需要的是这样

     gr       No new_column
       <fct> <int>      <dbl>
     1 a       100        200
     2 a       101        199
     3 a       102        198
     4 a       103        197
     5 a       104        196
     6 a       105        195
     7 b       200        250
     8 b       201        249
     9 b       202        248
    10 b       203        247
    11 b       204        246
    12 b       205        245
    

    我搞不懂怎么连续减少?

    谢谢。

    2 回复  |  直到 8 年前
        1
  •  1
  •   tyluRp    8 年前

    不是最优雅的回答,但同时,这可能会起作用:

    library(dplyr)
    
    test %>% 
      mutate(A = case_when(gr == "a" ~ 100,
                           gr == "b" ~ 50,
                           TRUE ~ NA_real_)) %>% 
      group_by(gr) %>% 
      mutate(B = (1:NROW(gr) - 1) * 2,
             New_Column = No + A - B)
    
    # A tibble: 12 x 5
    # Groups:   gr [2]
       gr       No     A     B New_Column
       <fct> <int> <dbl> <dbl>      <dbl>
     1 a       100   100     0        200
     2 a       101   100     2        199
     3 a       102   100     4        198
     4 a       103   100     6        197
     5 a       104   100     8        196
     6 a       105   100    10        195
     7 b       200    50     0        250
     8 b       201    50     2        249
     9 b       202    50     4        248
    10 b       203    50     6        247
    11 b       204    50     8        246
    12 b       205    50    10        245
    

    添加 select(gr, No, New_Column) 在链条的末端 gr , No New_Column 只有。我离开其他专栏只是为了说明发生了什么。

    如果你想把它包装成一个函数,你可以这样做:

    desc_func <- function(group_var, condition, if_true_add, if_false_add, to_number) {
      ifelse(
        group_var == condition, 
        to_number + if_true_add - (1:NROW(group_var) - 1) * 2, 
        to_number + if_false_add - (1:NROW(group_var) - 1) * 2)
    }
    
    test %>% 
      group_by(gr) %>% 
      mutate(test_var = desc_func(gr, "a", 100, 50, No))
    
    # A tibble: 12 x 3
    # Groups:   gr [2]
       gr       No test_var
       <fct> <int>    <dbl>
     1 a       100      200
     2 a       101      199
     3 a       102      198
     4 a       103      197
     5 a       104      196
     6 a       105      195
     7 b       200      250
     8 b       201      249
     9 b       202      248
    10 b       203      247
    11 b       204      246
    12 b       205      245
    
        2
  •  1
  •   akrun    8 年前

    这里有个方法 base R

    test$New <- with(test, No + c(100, 50)[cumsum(!duplicated(gr))] - 2*(No %% 100))
    test$New
    #[1] 200 199 198 197 196 195 250 249 248 247 246 245
    

    或与 match

    with(test, No + c(100, 50)[match(gr, unique(gr))] - 2*(No %% 100))
    
    推荐文章