【问题标题】:Conditional update referring to other columns引用其他列的条件更新
【发布时间】:2015-05-16 13:49:12
【问题描述】:

我正在尝试在 R 中对一些形状类似于下面给出的数据进行条件更新。

规则是,如果类别 Z 的值 == 0,则将其设置为同一类型中类别 X 的值。

作为一个 R 新手并且没有太多时间,我最终使用了一个循环,因为我看不到如何使用 by() 更新值,但我希望有一个更明显的解决方案。

Type    Category    Value
A       X           5
A       Y           2
A       Z           3
B       X           6
B       Y           2
B       Z           0
C       X           7
C       Y           2
C       Z           0

我想要的输出是:

Type    Category    Value
A       X           5
A       Y           2
A       Z           3 <- remains 3
B       X           6
B       Y           2
B       Z           6 <- updated to 6
C       X           7
C       Y           2
C       Z           7 <- updated to 7

提前致谢。

【问题讨论】:

    标签: r vectorization conditional-statements


    【解决方案1】:

    这是使用dplyr 包的解决方案:

    library(dplyr)
    
    # Assume your data frame is called "dat"
    dat = dat %>% group_by(Type) %>%
      mutate(ValueNew = ifelse(Category=="Z" & Value==0, Value[Category=="X"], Value))
    
      Type Category Value ValueNew
    1    A        X     5        5
    2    A        Y     2        2
    3    A        Z     3        3
    4    B        X     6        6
    5    B        Y     2        2
    6    B        Z     0        6
    7    C        X     7        7
    8    C        Y     2        2
    9    C        Z     0        7
    

    【讨论】:

      【解决方案2】:
      library(data.table)
       setDT(mydf)[, value1 := ifelse(Value != 0L & Category == "Z", 
                                Value, Value[Category == "X"]), by = Type]
      mydf
      #    Type Category Value value1
      # 1:    A        X     5      5
      # 2:    A        Y     2      2
      # 3:    A        Z     3      3
      # 4:    B        X     6      6
      # 5:    B        Y     2      2
      # 6:    B        Z     0      6
      # 7:    C        X     7      7
      # 8:    C        Y     2      2
      # 9:    C        Z     0      7
      

      【讨论】:

        【解决方案3】:

        宽格式的变异有时更直观:

        library(dplyr)
        library(tidyr)
        
        df1 %>%
          spread(Category, Value) %>%
          mutate( Z = ifelse( Z == 0, X, Z)) %>%
          gather( Category, Value, -Type) %>%
          arrange(Type, Category, Value)
        
        #   Type Category Value
        # 1    A        X     5
        # 2    A        Y     2
        # 3    A        Z     3
        # 4    B        X     6
        # 5    B        Y     2
        # 6    B        Z     6
        # 7    C        X     7
        # 8    C        Y     2
        # 9    C        Z     7  
        

        如果你可以接受宽幅,那就只有枢轴和“Z 规则”:

        df1 %>%
          spread(Category, Value) %>%
          mutate( Z = ifelse( Z == 0, X, Z))
        
        #   Type X Y Z
        # 1    A 5 2 3
        # 2    B 6 2 6
        # 3    C 7 2 7
        

        【讨论】:

          【解决方案4】:

          另一个使用data.table的选项

          library(data.table)
          setDT(dat)[, Value := Value + Value[Category == 'X'] * 
                         (Category == 'Z' & Value == 0L), by = Type][]
          #    Type Category Value
          #1:    A        X     5
          #2:    A        Y     2
          #3:    A        Z     3
          #4:    B        X     6
          #5:    B        Y     2
          #6:    B        Z     6
          #7:    C        X     7
          #8:    C        Y     2
          #9:    C        Z     7
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-07-11
            • 2015-04-23
            • 2018-07-30
            • 2020-12-12
            • 2021-08-30
            • 2020-11-01
            • 1970-01-01
            相关资源
            最近更新 更多