Divide by a specified member in a group in R
1
0
Entering edit mode
4 weeks ago
mbk0asis ▴ 630

I'd like to divide the values of t2~t4 by t1 in each group in R from the data like below.

group   type    value
A   t1  10
A   t2  20
A   t3  30
A   t4  40
B   t1  20
B   t2  40
B   t3  60
B   t4  80


I tried to un-melt by type but I think there would be better way to do it.

Any ideas?

Thank you!

R dplyr • 301 views
4
Entering edit mode
4 weeks ago
Dunois ★ 1.3k

Does this work?

library(dplyr)
library(magrittr)

df <- read.table(text = "group   type    value
A   t1  10
A   t2  20
A   t3  30
A   t4  40
B   t1  20
B   t2  40
B   t3  60
B   t4  80
", header = TRUE)

df %>%
group_by(group) %>%
mutate(t1val = value[1]) %>%
ungroup() %>%
mutate(oth_by_t1 = value/t1val)

# # A tibble: 8 x 5
#   group type  value t1val oth_by_t1
#   <chr> <chr> <int> <int>     <dbl>
# 1 A     t1       10    10         1
# 2 A     t2       20    10         2
# 3 A     t3       30    10         3
# 4 A     t4       40    10         4
# 5 B     t1       20    20         1
# 6 B     t2       40    20         2
# 7 B     t3       60    20         3
# 8 B     t4       80    20         4


You could, of course, skip that extra assignment (mutate(t1val = value[1])), and just have this instead (it works all the same):

df %>%
group_by(group) %>%
mutate(oth_by_t1 = value/value[1]) %>%
ungroup()

0
Entering edit mode

Wow! That's exactly what I wanted.

Thnak you!!

0
Entering edit mode

Dunois,

I have another question.

If I want to add a column containing number of members in each group, how can I do it?

group type value count
A   t1  10  4
A   t2  20  4
A   t3  30  4
A   t4  40  4
B   t1  20  3
B   t2  40  3
B   t3  60  3

2
Entering edit mode

Here you go:

df %>% group_by(group) %>% mutate(ngrp = n()) %>% ungroup()

# # A tibble: 8 x 4
# # Groups:   group [2]
#   group type  value  ngrp
#   <chr> <chr> <int> <int>
# 1 A     t1       10     4
# 2 A     t2       20     4
# 3 A     t3       30     4
# 4 A     t4       40     4
# 5 B     t1       20     4
# 6 B     t2       40     4
# 7 B     t3       60     4
# 8 B     t4       80     4


Also, please note, the code snippets I provided are using uni-directional pipes (%>%). So these chains do not store the output you see at the terminal. To store the output, point the entire chain at a new variable like so (for example):

new_df <- df %>% group_by(group) %>% mutate(ngrp = n()) %>% ungroup()


Or, if you just want to update df itself with the new columns and whatnot, use a bi-directional pipe as the first operator in the chain like so:

df %<>% group_by(group) %>% mutate(ngrp = n()) %>% ungroup()


(Just wanted to mention this in case you weren't aware of this, and ended up wondering why your results are wrong much later.)

0
Entering edit mode

Thank you again for your kind answers!

0
Entering edit mode

You're welcome!!