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

嵌套ifelse在R中,带有“conditionhaslength>1”警告

  •  0
  • Bubbles  · 技术社区  · 1 年前

    我有以下数据框架,并希望强加一些规则来生成新的值:

    column_1<-c("B","B","B","B","A","A","A","A")
    column_2<-c("L","L","B","B","L","L","B","B")
    column_3<-c("c","b","c","b","c","b","c","b")
    column_4<-rep(1)
    column_5<-rep(0.5)
    column_6<-rep(2)
    
    df_test<-data.frame(column_1,column_2,column_3,column_4,column_5,column_6)
    #concatenating column 1,2,3 as a flag, naming it column 7
    df_test$column_7<-paste0(df_test$column_1,df_test$column_2,df_test$column_3)
    
    > df_test
      column_1 column_2 column_3 column_4 column_5 column_6 column_7
    1        B        L        c        1      0.5        2      BLc
    2        B        L        b        1      0.5        2      BLb
    3        B        B        c        1      0.5        2      BBc
    4        B        B        b        1      0.5        2      BBb
    5        A        L        c        1      0.5        2      ALc
    6        A        L        b        1      0.5        2      ALb
    7        A        B        c        1      0.5        2      ABc
    8        A        B        b        1      0.5        2      ABb
    
    #rule 1: if column_7=="BLc|BBb", then df_test$result will be equal to column 4 +column 5 +column_6
    #rule 2: if column_7=="BLb|BBc", then df_test$result will be equal to column 4 +column 5 -column_6
    #rule 3: if column_7=="ALc|ABb", then df_test$result will be equal to column 4 -column 5 -column_6
    #rule 4: if column_7=="ABc|ALb", then df_test$result will be equal to column 4 -column 5 +column_6
    

    要转换规则,我有以下片段:

    df_test$result<-if(df_test$column_7=="BLc|BBb"){
      df_test$column_4+df_test$column_5+df_test$column_6
    }else{
      if(df_test$column_7=="BLb|BBc"){
        df_test$column_4+df_test$column_5-df_test$column_6
      }else{
        if(df_test$column_7=="ALc|ABb"){
          df_test$column_4-df_test$column_5-df_test$column_6
        } else{
          if(df_test$column_7=="ABc|ALb"){
            df_test$column_4-df_test$column_5+df_test$column_6
          }
        }
      }
    }
    
    Warning messages:
    1: In if (df_test$column_7 == "BLc|BBb") { :
      the condition has length > 1 and only the first element will be used
    2: In if (df_test$column_7 == "BLb|BBc") { :
      the condition has length > 1 and only the first element will be used
    3: In if (df_test$column_7 == "ALc|ABb") { :
      the condition has length > 1 and only the first element will be used
    4: In if (df_test$column_7 == "ABc|ALb") { :
      the condition has length > 1 and only the first element will be used
    
    > print(df_test$result)
    NULL
    

    在这里,我假设我的嵌套方式,如果其他地方出了问题,你能给我一些提示吗?

    如果一切顺利,预计会看到以下内容:

    > data.frame(desired_column_8)
      desired_column_8
    1              3.5
    2             -0.5
    3             -0.5
    4              3.5
    5             -1.5
    6              2.5
    7              2.5
    8             -1.5
    

    不管怎样,感谢大家花时间查看这篇文章。

    更新1:尝试dplyr::case_when

    library(dplyr)
    df_test<-df_test %>%
      mutate(column_8=case_when(column_7=="BLc|BBb" ~df_test$column_4+df_test$column_5+df_test$column_6,
                                column_7=="BLb|BBc" ~df_test$column_4+df_test$column_5-df_test$column_6,
                                column_7=="ALc|ABb" ~df_test$column_4-df_test$column_5-df_test$column_6,
                                column_7=="ABc|ALb"~df_test$column_4-df_test$column_5+df_test$column_6))
    
    
    > df_test
      column_1 column_2 column_3 column_4 column_5 column_6 column_7 column_8
    1        B        L        c        1      0.5        2      BLc       NA
    2        B        L        b        1      0.5        2      BLb       NA
    3        B        B        c        1      0.5        2      BBc       NA
    4        B        B        b        1      0.5        2      BBb       NA
    5        A        L        c        1      0.5        2      ALc       NA
    6        A        L        b        1      0.5        2      ALb       NA
    7        A        B        c        1      0.5        2      ABc       NA
    8        A        B        b        1      0.5        2      ABb       NA
    > 
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   jblood94    1 年前

    使用的选项 match 。它可能比嵌套更具性能 ifelse s

    codes <- c("BLc", "BBb", "BLb", "BBc", "ABc", "ALb", "ALc", "ABb")
    transform(
      df_test,
      result = {
        i <- (match(column_7, codes) - 1)%/%2
        column_4 + column_5*(1 - 2*(i%/%2)) + column_6*(1 - 2*(i%%2))
      }
    )
    #>   column_1 column_2 column_3 column_4 column_5 column_6 column_7 result
    #> 1        B        L        c        1      0.5        2      BLc    3.5
    #> 2        B        L        b        1      0.5        2      BLb   -0.5
    #> 3        B        B        c        1      0.5        2      BBc   -0.5
    #> 4        B        B        b        1      0.5        2      BBb    3.5
    #> 5        A        L        c        1      0.5        2      ALc   -1.5
    #> 6        A        L        b        1      0.5        2      ALb    2.5
    #> 7        A        B        c        1      0.5        2      ABc    2.5
    #> 8        A        B        b        1      0.5        2      ABb   -1.5
    
        2
  •  1
  •   B. Christian Kamgang    1 年前

    您可以使用regex解决您的问题,如下所示:

    library(dplyr)
    library(stringr)
    
    df_test %>%
      mutate(column_8=case_when(str_detect(column_7, "BLc|BBb") ~ column_4 + column_5 + column_6,
                                str_detect(column_7, "BLb|BBc") ~ column_4 + column_5 - column_6,
                                str_detect(column_7, "ALc|ABb") ~ column_4 - column_5 - column_6,
                                str_detect(column_7, "ABc|ALb") ~ column_4 - column_5 + column_6))
    
      column_1 column_2 column_3 column_4 column_5 column_6 column_7 column_8
    1        B        L        c        1      0.5        2      BLc      3.5
    2        B        L        b        1      0.5        2      BLb     -0.5
    3        B        B        c        1      0.5        2      BBc     -0.5
    4        B        B        b        1      0.5        2      BBb      3.5
    5        A        L        c        1      0.5        2      ALc     -1.5
    6        A        L        b        1      0.5        2      ALb      2.5
    7        A        B        c        1      0.5        2      ABc      2.5
    8        A        B        b        1      0.5        2      ABb     -1.5