Измените значение последнего элемента группирующей переменной в другом векторе с помощью dplyr

#r #dplyr

Вопрос:

Я хочу изменить следующий фрейм данных таким образом, чтобы все в x ping == 3 NA :

Данные

 d <- tibble(id = rep(c(1001, 1002), each = 6),
            day = rep(c(1, 1, 1, 2, 2, 2), 2),
            ping = rep(1:3, 4),
            x = rnorm(12, 5, 4),
            y = x*0.3   rnorm(12))

# A tibble: 12 x 5
      id   day  ping     x      y
   <dbl> <dbl> <int> <dbl>  <dbl>
 1  1001     1     1  5.63  0.783
 2  1001     1     2  7.02  3.41 
 3  1001     1     3  1.72  1.29 
 4  1001     2     1 -3.00  0.154
 5  1001     2     2  3.08 -0.485
 6  1001     2     3  5.34  2.60 
 7  1002     1     1  1.42 -1.27 
 8  1002     1     2  1.31 -0.139
 9  1002     1     3  6.32  0.524
10  1002     2     1  4.43 -0.878
11  1002     2     2  6.74  3.84 
12  1002     2     3  4.79  0.782
 

Желаемый Результат

 # A tibble: 12 x 5
      id   day  ping     x      y
   <dbl> <dbl> <int> <dbl>  <dbl>
 1  1001     1     1  5.63  0.783
 2  1001     1     2  7.02  3.41 
 3  1001     1     3  NA    1.29 
 4  1001     2     1 -3.00  0.154
 5  1001     2     2  3.08 -0.485
 6  1001     2     3  NA    2.60 
 7  1002     1     1  1.42 -1.27 
 8  1002     1     2  1.31 -0.139
 9  1002     1     3  NA    0.524
10  1002     2     1  4.43 -0.878
11  1002     2     2  6.74  3.84 
12  1002     2     3  NA    0.782
 

Как я могу это сделать с dplyr помощью ?

 d %>%
    group_by(day) %>%
    mutate(...)
 

Комментарии:

1. Попробуй d %>% mutate(x = ifelse(ping == 3, NA, x))

2. Что, если бы я не знал последней ценности ping «внутри day «?

3. Что вы подразумеваете под последним значением элемента группировки? Что, если ping 1,3,2 бы было второе значение x be NA ?

Ответ №1:

Вы можете сделать это без группировки. Я думаю, что, основываясь на ваших новых требованиях, это может помочь:

 library(dplyr)

d %>%
  group_by(id, day) %>%
  arrange(ping) %>%
  mutate(x = ifelse(row_number() == n(), NA, x)) %>%
  ungroup() %>%
  arrange(id, day)

# A tibble: 12 x 5
      id   day  ping      x       y
   <dbl> <dbl> <int>  <dbl>   <dbl>
 1  1001     1     1  5.19   2.54  
 2  1001     1     2  0.582  1.06  
 3  1001     1     3 NA      2.63  
 4  1001     2     1  7.32   3.16  
 5  1001     2     2  2.37  -0.104 
 6  1001     2     3 NA      3.65  
 7  1002     1     1  0.249 -0.0869
 8  1002     1     2  5.61   3.62  
 9  1002     1     3 NA      1.92  
10  1002     2     1 11.5    3.79  
11  1002     2     2  5.14   1.85  
12  1002     2     3 NA      2.68  
 

Комментарии:

1. Что, если бы я не знал последней ценности ping «внутри day «?

2. В этом случае вам придется использовать группировку. Но у меня есть один вопрос в таком случае, хотели бы вы все еще получить тот же результат? поскольку весь день 1 s и 2 s будут находиться в одной и той же группе, ваши NA ценности будут составлять половину из них. Если это так, нам нужна дополнительная переменная для группировки.

3. Я хотел бы x ping , чтобы в каждом day из них было последнее NA . Таким образом, если бы последний пинг был 4, то x для пинга 3 оставался бы ненулевым. Я обновлю данные в этом посте.

4. Я понимаю , но у вас есть 2 набора дня 1 и два набора дня 2 , мы должны поместить их в одну группу?

5. Тогда я этого не заметил id . Мы можем им воспользоваться. Проверьте мои обновления здесь.

Ответ №2:

для каждого id значения вы можете заменить x значение на NA где ping имеет max значение.

 library(dplyr)

d %>%
  group_by(id) %>%
  #group by day as well if you want to consider each day within id differently.
  #group_by(id, day) %>%
  mutate(x = replace(x, ping == max(ping), NA)) %>%
  ungroup

#     id   day  ping      x      y
#   <dbl> <dbl> <int>  <dbl>  <dbl>
# 1  1001     1     1  9.84   2.41 
# 2  1001     1     2  4.37   1.54 
# 3  1001     1     3 NA      2.37 
# 4  1001     2     1  0.305 -0.537
# 5  1001     2     2  6.96   1.92 
# 6  1001     2     3 NA      2.38 
# 7  1002     1     1  5.25   1.25 
# 8  1002     1     2 13.4    3.51 
# 9  1002     1     3 NA      2.75 
#10  1002     2     1  7.62   0.896
#11  1002     2     2  5.01   2.00 
#12  1002     2     3 NA      2.96