My current project contains data that's got a structure like:
my_df <- tibble(
zn = c("hm","hm", "hm", "h60","h60","h60", "h85","h85","h85"),
nm = c("c", "cA", "cB", "c","cA", "cB", "c","cA", "cB"),
val = c(60, 40, 20, 250, 150, 100, 400, 250, 150),
znt = c(100, 100, 100, 300, 300, 300, 500, 500, 500),
)
my_df
# A tibble: 9 x 4
zn nm val znt
<chr> <chr> <dbl> <dbl>
1 hm c 60 100
2 hm cA 40 100
3 hm cB 20 100
4 h60 c 250 300
5 h60 cA 150 300
6 h60 cB 100 300
7 h85 c 400 500
8 h85 cA 250 500
9 h85 cB 150 500
And I would like to add a new variable, c0, whose value is defined c0 = znt - c for each zn. The final result would look like:
# A tibble: 12 x 4
zn nm val znt
<chr> <chr> <dbl> <dbl>
1 hm c0 40 100
2 hm c 60 100
3 hm cA 40 100
4 hm cB 20 100
5 h60 c0 50 300
6 h60 c 250 300
7 h60 cA 150 300
8 h60 cB 100 300
9 h85 c0 100 500
10 h85 c 400 500
11 h85 cA 250 500
12 h85 cB 150 500
I have an idea about how to do it but it seems very convoluted and I'm hoping there's a better way. If this could be accomplished using something from the tidyverse that'd be awesome, too.
Another option:
library(tidyverse)
my_df %>%
group_split(zn) %>%
map_dfr(~ add_row(.data = .,
zn = .$zn[1],
nm = 'c0',
val = .$znt[1] - .$val[.$nm == 'c'],
znt = .$znt[1],
.before = 1))
Output:
# A tibble: 12 x 4
zn nm val znt
* <chr> <chr> <dbl> <dbl>
1 h60 c0 50 300
2 h60 c 250 300
3 h60 cA 150 300
4 h60 cB 100 300
5 h85 c0 100 500
6 h85 c 400 500
7 h85 cA 250 500
8 h85 cB 150 500
9 hm c0 40 100
10 hm c 60 100
11 hm cA 40 100
12 hm cB 20 100
my_df %>%
bind_rows(my_df %>% filter(nm == "c") %>%
mutate(nm = "c0" , val = znt - val)) %>%
arrange(zn, nm)
gives
zn nm val znt
<chr> <chr> <dbl> <dbl>
1 h60 c 250 300
2 h60 c0 50 300
3 h60 cA 150 300
4 h60 cB 100 300
5 h85 c 400 500
6 h85 c0 100 500
7 h85 cA 250 500
8 h85 cB 150 500
9 hm c 60 100
10 hm c0 40 100
11 hm cA 40 100
12 hm cB 20 100
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