Calculate percentage when all values are in the same column of a dataframe in R

Viewed 157

I have the following data frame

x <- data.frame("treatment"= c(1, 1, 1, 1, 2, 2, 2, 2), 
              "Time" = c(0, 30, 60, 180, 0, 30, 60, 180), 
              "cells_alive" = c(500, 470, 100, 20, 476, 310, 99, 2))

In this experiment I have two treatments, where I measure the number of alive cells over time. The number of cells at time 0 is the initial number of cells for that treatment. I need to calculate the percentage of cells alive at each time in a new column. So in the case of treatment 1 it would be 500/500, 470/500, 100/500 and so on. Any ideas of how to calculate this?

Thanks

3 Answers
require(tidyverse)

x %>% 
left_join(x %>% select(treatment, cells_alive) %>% 
group_by(treatment) %>% 
top_n(1) %>% 
ungroup(), by = "treatment") %>% 
mutate(cells_alive_per = cells_alive.x/cells_alive.y)

Using data.table

library(data.table)
setDT(x) #converting x to data.table 
x[,.(Time, value = cells_alive / cells_alive[which(Time == 0)]),treatment]

#output
   treatment Time       value
1:         1    0 1.000000000
2:         1   30 0.940000000
3:         1   60 0.200000000
4:         1  180 0.040000000
5:         2    0 1.000000000
6:         2   30 0.651260504
7:         2   60 0.207983193
8:         2  180 0.004201681

After a dplyr and a data.table version have been posted, for the sake of completeness here is one that does not need package installation:

stack(tapply(x$cells_alive, x$treatment, function(ca) ca / ca[1] ))

which gives

> stack(tapply(x$cells_alive, x$treatment, function(ca) ca / ca[1] ))
       values ind
1 1.000000000   1
2 0.940000000   1
3 0.200000000   1
4 0.040000000   1
5 1.000000000   2
6 0.651260504   2
7 0.207983193   2
8 0.004201681   2
Related