This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Divide by a specified member in a group in R

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

1 answer

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()

Wow! That's exactly what I wanted.

Thnak you!!

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

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.)

Thank you again for your kind answers!

Log in to answer this question.