#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
beNA
?
Ответ №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