Создать новый столбец на основе условия из другого столбца на группу, используя аккуратную оценку - PullRequest
1 голос
/ 11 мая 2019

Аналогично этому вопросу , но вместо этого я хочу использовать аккуратную оценку.

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 1 имеет newValue из 2, потому что 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

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 11 мая 2019

Мы можем поместить оценку в скобках.В противном случае он может попытаться оценить все выражение (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 голосов
/ 11 мая 2019

Также вы можете использовать от 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`)") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...