Divide by a specified member in a group in R
1
0
Entering edit mode
3.4 years ago
mbk0asis ▴ 700

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.2k views
ADD COMMENT
4
Entering edit mode
3.4 years ago
Dunois ★ 2.8k

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()
ADD COMMENT
0
Entering edit mode

Wow! That's exactly what I wanted.

Thnak you!!

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

ADD REPLY
0
Entering edit mode

Thank you again for your kind answers!

ADD REPLY
0
Entering edit mode

You're welcome!!

ADD REPLY

Login before adding your answer.

Traffic: 1995 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6