Segue uma possivel solução com o aggregate, mas ele faz exatamente a mesma coisa que o tapply, so mudam os argumentos.

> temp1<-aggregate(x=d1$acidezKOH, by=list(d1$Tipo,d1$Trat,d1$Tempo), FUN=mean)
> temp2<-aggregate(x=d1$acidezOLEIC, by=list(d1$Tipo,d1$Trat,d1$Tempo), FUN=mean)
> dmedia<-data.frame(temp1,temp2[,4])
> colnames(dmedia)
[1] "Group.1"    "Group.2"    "Group.3"    "x"          "temp2...4."
> colnames(dmedia)<-c("Tipo","Trat","Tempo","acidezKOH", "acidezOLEIC")
> head(dmedia)
  Tipo Trat Tempo acidezKOH acidezOLEIC
1  TI1  TR1     0  2.320000   1.1666667
2  TI2  TR1     0  0.230000   0.1100000
3  TI3  TR1     0  0.090000   0.0400000
4  TI1  TR2     0  3.533333   1.7733333
5  TI2  TR2     0  0.270000   0.1333333
6  TI3  TR2     0  0.140000   0.0700000
> class(dmedia)
[1] "data.frame"

Vai existir muitas formas de isso, alguma provavelmente mais rápidas, mas assim eu so calculei as médias guardando em dois objetos temporariors, depois eu coloquei tudo num dataframe e modifiquei os nomes das colunas para ficar bonitinho. Ja da para quebrar o galho.


--
Grato
Augusto C. A. Ribas
 
Site Pessoal: http://recologia.com.br/
Github: https://github.com/Squiercg
Lattes: http://lattes.cnpq.br/7355685961127056