I want to sum the other columns by those factors.
This is what rowsum is for:
rowsum(data[, -(1:2)], data$Trophic.Mode)
#R>             Sample1 Sample2 Sample3 Sample4
#R> Pathotroph       11       4       6       5
#R> Symbiotroph       4       5       6       1
This is hard to beat both in terms of keystrokes and computation time:
# simulate your ~2700 row data set
set.seed(1)
n <- 2700L
sim_dat <- data.frame(
  Trophic.Mode = sample.int(5, n, replace = TRUE), 
  sample       = matrix(sample.int(10, n * 4L, replace = TRUE), n))
colnames(sim_dat)[-1] <- paste0("sample", 1:4)
head(sim_dat, 3)
#R>   Trophic.Mode sample1 sample2 sample3 sample4
#R> 1            1       9       6       9       6
#R> 2            4       1       6       3       1
#R> 3            1       9       9      10       9
# check that we get the same
r1 <- aggregate(. ~ Trophic.Mode, data = sim_dat, FUN = sum)
r2 <- rowsum(sim_dat[, -1], sim_dat$Trophic.Mode)
all.equal(r1[, -1], r2, check.attributes = FALSE)
#R> [1] TRUE
library(tidyverse)
r3 <- sim_dat %>% 
  group_by(Trophic.Mode) %>%
  summarise_all(sum) %>%
  ungroup()
all.equal(r3[, -1], r2, check.attributes = FALSE)
#R> [1] TRUE
# check the computation time
bench::mark(
  aggregate = aggregate(. ~ Trophic.Mode, data = sim_dat, FUN = sum), 
  rowsum    = rowsum(sim_dat[, -1], sim_dat$Trophic.Mode), 
  tidy      = sim_dat %>% 
    group_by(Trophic.Mode) %>%
    summarise_all(sum) %>%
    ungroup(),
  min_time = 2, check = FALSE)
#R> # A tibble: 3 x 13
#R>   expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time 
#R>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> 
#R> 1 aggregate    2.28ms   2.45ms      396.    1.37MB    17.4    612    27      1.55s 
#R> 2 rowsum     110.93µs  129.8µs     7449.   53.23KB    11.2   9985    15      1.34s 
#R> 3 tidy         3.49ms   4.63ms      209.   93.41KB     6.56   383    12      1.83s
That is almost 20 times faster than the other methods but a few milliseconds is nothing to start with...
Update
As requested, here is the benchmark with n <- 500000L (500k rows) and without the ungroup:
bench::mark(
  aggregate = aggregate(. ~ Trophic.Mode, data = sim_dat, FUN = sum), 
  rowsum    = rowsum(sim_dat[, -1], sim_dat$Trophic.Mode), 
  tidy      = sim_dat %>% 
    group_by(Trophic.Mode) %>%
    summarise_all(sum),
  min_time = 2, check = FALSE)
#R> # A tibble: 3 x 13
#R>   expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time 
#R>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> 
#R> 1 aggregate   203.5ms  264.5ms      3.64  234.56MB     25.5     8    56      2.19s 
#R> 2 rowsum         11ms   11.2ms     84.8     7.82MB     14.0   170    28         2s 
#R> 3 tidy         12.8ms   13.4ms     64.8    17.36MB     25.9   130    52         2s
and for n <- 10000000L (10M):
bench::mark(
  aggregate = aggregate(. ~ Trophic.Mode, data = sim_dat, FUN = sum), 
  rowsum    = rowsum(sim_dat[, -1], sim_dat$Trophic.Mode), 
  tidy      = sim_dat %>% 
    group_by(Trophic.Mode) %>%
    summarise_all(sum),
  min_time = 30, check = FALSE)
#R>   expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time 
#R>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> 
#R> 1 aggregate     5.82s    5.92s     0.168    5.05GB    2.18      6    78      35.8s 
#R> 2 rowsum     275.46ms 285.37ms     3.41   204.29MB    0.796   103    24      30.2s 
#R> 3 tidy       233.38ms 264.47ms     3.66   331.03MB    2.03    110    61      30.1s
It turns out though that there is very little difference for larger data sets.