【问题标题】:Create new column based on condition from other column per group using tidy evaluation使用整洁的评估根据每组其他列的条件创建新列
【发布时间】:2019-09-28 21:57:53
【问题描述】:

question 类似,但我想改用 tidy 评估。

df = data.frame(group = c(1,1,1,2,2,2,3,3,3), 
                date  = c(1,2,3,4,5,6,7,8,9),
                speed = c(3,4,3,4,5,6,6,4,9))
> df
  group date speed
1     1    1     3
2     1    2     4
3     1    3     3
4     2    4     4
5     2    5     5
6     2    6     6
7     3    7     6
8     3    8     4
9     3    9     9

任务是创建一个新列 (newValue),其值等于 date 列(每组)的值,条件是:speed == 4。示例:group 1newValue2,因为 date[speed==4] = 2

    group date speed newValue
1     1    1     3        2
2     1    2     4        2
3     1    3     3        2
4     2    4     4        4
5     2    5     5        4
6     2    6     6        4
7     3    7     6        8
8     3    8     4        8
9     3    9     9        8

它在没有整洁的评估的情况下工作

df %>%
  group_by(group) %>%
  mutate(newValue=date[speed==4L])
#> # A tibble: 9 x 4
#> # Groups:   group [3]
#>   group  date speed newValue
#>   <dbl> <dbl> <dbl>    <dbl>
#> 1     1     1     3        2
#> 2     1     2     4        2
#> 3     1     3     3        2
#> 4     2     4     4        4
#> 5     2     5     5        4
#> 6     2     6     6        4
#> 7     3     7     6        8
#> 8     3     8     4        8
#> 9     3     9     9        8

但是在整洁的评估中出现了错误

my_fu <- function(df, filter_var){
  filter_var <- sym(filter_var)
  df <- df %>%
    group_by(group) %>%
    mutate(newValue=!!filter_var[speed==4L])
}

my_fu(df, "date")
#> Error in quos(..., .named = TRUE): object 'speed' not found

提前致谢。

【问题讨论】:

    标签: r dplyr tidyeval


    【解决方案1】:

    我们可以将评估放在括号内。否则,它可能会尝试评估整个表达式 (filter_var[speed = 4L]) 而不是单独的 filter_var

    library(rlang)
    library(dplyr)
    my_fu <- function(df, filter_var){
         filter_var <- sym(filter_var)
       df %>%
          group_by(group) %>%
         mutate(newValue=(!!filter_var)[speed==4L])
        }
    
    my_fu(df, "date")
    # A tibble: 9 x 4
    # Groups:   group [3]
    #  group  date speed newValue
    #  <dbl> <dbl> <dbl>    <dbl>
    #1     1     1     3        2
    #2     1     2     4        2
    #3     1     3     3        2
    #4     2     4     4        4
    #5     2     5     5        4
    #6     2     6     6        4
    #7     3     7     6        8
    #8     3     8     4        8
    #9     3     9     9        8
    

    【讨论】:

      【解决方案2】:

      另外,您可以使用sqldf。加入 df 并对其进行约束:

      library(sqldf)
      df = data.frame(group = c(1,1,1,2,2,2,3,3,3), 
                  date  = c(1,2,3,4,5,6,7,8,9),
                  speed = c(3,4,3,4,5,6,6,4,9))
      
      sqldf("SELECT df_origin.*, df4.`date` new_value FROM 
             df df_origin join (SELECT `group`, `date` FROM df WHERE speed = 4) df4 
                          on (df_origin.`group` = df4.`group`)") 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多