Run a custom function on a data frame in R, by group

Using dplyr

library(dplyr)
df %>% 
   group_by(tm) %>%
   do(data.frame(val=calc(.)))
#  tm      val
#1  1 1.665882
#2  2 1.504545
#3  3 1.838000

If we change the function slightly to include multiple arguments, this could also work with summarise

 calc1 <- function(d1, t1, h1, p1){
      (1.27*sum(d1) + 1.62*sum(t1) + 2.10*sum(h1) )/sum(p1) }
 df %>%
     group_by(tm) %>% 
     summarise(val=calc1(d, t, h, p))
 #  tm      val
 #1  1 1.665882
 #2  2 1.504545
 #3  3 1.838000

library(plyr)
ddply(df, .(tm), calc)

You can try split:

sapply(split(df, tm), calc)

#       1        2        3 
#1.665882 1.504545 1.838000 

If you want a list lapply(split(df, tm), calc).

Or with data.table:

library(data.table)

setDT(df)[,calc(.SD),tm]
#   tm       V1
#1:  1 1.665882
#2:  2 1.504545
#3:  3 1.838000