I have an example df:
df <- structure(list(A = c('A', 'B', 'C', 'D', 'E', 'F'),
B = c(2, 5, 8, 12, 15, 18)), class = "data.frame", row.names = c(NA, -6L))
A B
1 A 2
2 B 5
3 C 8
4 D 12
5 E 15
6 F 18
I'd like to add rows with with value B increased and decreased by 1 in groups like this:
A B
1 A 1
2 A 2
3 A 3
4 B 4
5 B 5
6 B 6
7 C 7
8 C 8
9 C 9
10 D 11
11 D 12
12 D 13
13 E 14
14 E 15
15 E 16
16 F 17
17 F 18
18 F 19
So I did something like this and it does the trick:
df %>%
group_by(A) %>%
complete(B = B + c(-1,1)) %>%
arrange(B)
However my real data has... let's say duplicated groups:
df <- structure(list(A = c('A', 'A', 'C', 'D', 'E', 'F'),
B = c(2, 5, 8, 12, 15, 18)), class = "data.frame", row.names = c(NA, -6L))
A B
1 A 2
2 A 5
3 C 8
4 D 12
5 E 15
6 F 18
And I still want to add 1 and -1 to each element in group leaving the original one and keeping the order in group:
A B
1 A 1
2 A 2
3 A 3
4 A 4
5 A 5
6 A 6
7 C 7
8 C 8
9 C 9
10 D 11
11 D 12
12 D 13
13 E 14
14 E 15
15 E 16
16 F 17
17 F 18
18 F 19
My solution doesn't work no more giving:
A B
1 A 1
2 A 2
3 A 5
4 A 6
5 C 7
6 C 8
(...)
Could you please show me how can I modify my somple dplyr code?
You can use unnest like below
df %>%
mutate(B = list(B + (-1:1)), .by = A) %>%
unnest(B)
which gives
# A tibble: 18 × 2
A B
<chr> <dbl>
1 A 1
2 A 2
3 A 3
4 B 4
5 B 5
6 B 6
7 C 7
8 C 8
9 C 9
10 D 11
11 D 12
12 D 13
13 E 14
14 E 15
15 E 16
16 F 17
17 F 18
18 F 19
Ok, I think I got it:
df %>%
mutate(B_plus_one = B + 1,
B_minus_one = B - 1) %>%
bind_rows(., mutate(., B = B_plus_one)) %>%
bind_rows(., mutate(., B = B_minus_one)) %>%
select(-B_plus_one, -B_minus_one) %>%
arrange(B) %>%
unique()
A B
1 A 1
3 A 2
4 A 3
5 A 4
7 A 5
8 A 6
9 C 7
11 C 8
12 C 9
13 D 11
15 D 12
16 D 13
17 E 14
19 E 15
20 E 16
21 F 17
23 F 18
24 F 19
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With