【问题标题】:R: generate a new column based on groups and conditionsR:根据组和条件生成新列
【发布时间】:2020-02-26 18:17:28
【问题描述】:

我有一个包含 4 列的数据框(其中一部分如下所示)。

第一列显示按数字排序的组:1、2、...。

我想生成一个新列“value4”。 对于每个组,如果组大小大于 2 (>=3),并且“value1”列中的所有值都大于 2 (>2) 或小于 -2 (

g   value1   value2  value3
1     1.1      8       1
1     1.2      8       1
1     1.3      9       1
2     3        10      5
2     4        11      5
2     5        0       4
2     6        1       6
3     -3       2       5
3     -4       3       10
3     -5       4       0
4     -3       1       0
4     -4       1       0

输出将是:

g   value1   value2  value3  value4
1     1.1      8       1       8  # for group "1", all the values in "value1" are <2, so the values from column "value2" are taken
1     1.2      8       1       8
1     1.3      9       1       9
2     3        10      5       5  # for group "2", all the values in "value1" are >2, median of numbers 5,5,4,6 from column "value3" is calculated  
2     4        11      5       5
2     5        0       4       5
2     6        1       6       5
3     -3       2       5       5  # for group "3", all the values in "value1" are < -2, median of numbers 5,10,0 from column "value3" is calculated      
3     -4       3       10      5
3     -5       4       0       5
4     -3       1       0       1  # group size less than 3, so the values from column "value2" are taken
4     -4       1       0       1

我想我可以使用聚合(),但我不知道如何整合条件。感谢您的宝贵时间和帮助。

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以使用包data.table如下:

    library(data.table)
    setDT(df)[, value4 := if(.N > 2 & (all(value1 > 2) | all(value1 < -2))) median(value3) else value2, g]
    

    【讨论】:

      【解决方案2】:

      这是case_when().*的理想情况

      您希望根据以下条件计算value4

      如果组大小 > 2 并且 组中所有value1 的绝对值 > 2 => 取value3 的中位数。否则使用value2

      library(dplyr)
      df %>%
        group_by(g) %>%
        mutate(value4 = case_when( (n() > 2) & (all(abs(value1) > 2)) ~ median(value3), 
                                  T ~ value2)
      

      *有人会认为我们可以在这里使用if_else(),因为只有一个条件,但由于某种原因,在条件中使用all() 时会失败。我认为它返回了多个值?不清楚,但也许其他人可以解释一下。

      【讨论】:

        【解决方案3】:

        根据条件,我们可以使用if/else 条件,利用groupsize (n()),如果all value1 小于-2 或大于2,则得到'value3' 的medianelsereturn 'value2'

        library(dplyr)
        df1 %>%       
           group_by(g) %>%
           mutate(value4 = if(n() > 2 & (all(value1 > 2)| all(value1 < -2))) median(value3) 
               else value2)
        # A tibble: 12 x 5
        # Groups:   g [4]
        #       g value1 value2 value3 value4
        #   <int>  <dbl>  <int>  <int>  <dbl>
        # 1     1    1.1      8      1      8
        # 2     1    1.2      8      1      8
        # 3     1    1.3      9      1      9
        # 4     2    3       10      5      5
        # 5     2    4       11      5      5
        # 6     2    5        0      4      5
        # 7     2    6        1      6      5
        # 8     3   -3        2      5      5
        # 9     3   -4        3     10      5
        #10     3   -5        4      0      5
        #11     4   -3        1      0      1
        #12     4   -4        1      0      1
        

        数据

        df1 <- structure(list(g = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
        4L, 4L), value1 = c(1.1, 1.2, 1.3, 3, 4, 5, 6, -3, -4, -5, -3, 
        -4), value2 = c(8L, 8L, 9L, 10L, 11L, 0L, 1L, 2L, 3L, 4L, 1L, 
        1L), value3 = c(1L, 1L, 1L, 5L, 5L, 4L, 6L, 5L, 10L, 0L, 0L, 
        0L)), class = "data.frame", row.names = c(NA, -12L))
        

        【讨论】:

        • 我不认为这是正确的。 g(和 g1)在示例中似乎是组 ID,但您正在将其评估为一个值。
        • @MokeEire 我认为你是对的。我会更新。我认为它是价值而不是 n()
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-09
        • 2017-03-22
        • 1970-01-01
        • 1970-01-01
        • 2022-11-22
        • 2023-01-13
        相关资源
        最近更新 更多