# applying two-sample t.test comparing multiple groups in two categories

I want to do a two-sample t.test comparing values from two regions for several groups. I know it must be a simple trick, but I couldn't find an answer so far.

This is a short version of my table. Several species each from 2 regions (There are generally 6 specimens per species available for each region).

species region   N15
ARGAFF     EQ    9.85
ARGAFF     EQ   10.42
ARGAFF     EQ   10.43
ARGAFF    OMZ   10.28
ARGAFF    OMZ   10.30
ARGAFF    OMZ   10.41
BATABY     EQ   10.57
BATABY     EQ   10.60
BATABY     EQ   10.68
BATABY    OMZ    9.21
BATABY    OMZ    9.29
BATABY    OMZ    9.67


I tried

spp<-split(SIA,species,drop=FALSE)


followed by

lapply(spp,function (x) t.test(N15~region))


I further tried

by(SIA[,3], SIA[, "species"], function (x) t.test(N15~region))


but both versions compute the test for all values (N.138, not just for individual species (N:12).

On the other hand

 by(SIA[,3], SIA[, "species"], t.test)


results in a one-sample test but for individual species.

• Does this one help? stackoverflow.com/questions/37474672/… Jun 1 '16 at 14:44
• @AntoniosK, what if there is another column named N16, and I want to do a test on that too with a result formatted like: # species N15 N16 # 1 ARGAFF PVALUE PVALUE # 2 BATABY PVALUE PVALUE is this possible? I actually want to post this as a comment, but you know, no sufficient reputation to do that. Jan 21 '18 at 12:06

There are various ways to do that, but I'm using a combination of dplyr and broom packages. The advantage of this process is that you export the t-test information as a dataset:

library(dplyr)
library(broom)

set.seed(9)

# example dataset
dt = data.frame(species = c(rep("ARGAFF",6), rep("BATABY",6)),
region = rep(c("EQ","OMZ"),6),
N15 = rnorm(12,10,1))

dt_result = dt %>% group_by(species) %>% do(tidy(t.test(N15~region, data=.)))

dt_result

#   species  estimate estimate1 estimate2 statistic   p.value parameter   conf.low conf.high
# 1  ARGAFF 0.6029705  9.842659  9.239688  1.381967 0.2439265  3.732157 -0.6434982  1.849439
# 2  BATABY 1.0238324 10.740491  9.716659  1.994738 0.1673019  2.300604 -0.9298488  2.977514


Hope it works for you.

First, in general it is a bad idea to attach a dataset. You can modify your lapply statement to do what you want I think.

set.seed(9)

# example dataset
SIA <- data.frame(species = as.factor(c(rep("ARGAFF",6), rep("BATABY",6))),
region = as.factor(rep(c("EQ","OMZ"),6)),
N15 = rnorm(12,10,1))

spp <- split(SIA, SIA$species,drop=FALSE) out <- vector("list", length = length(spp)) out <- lapply(1:length(spp),function (x) out[[x]]<- t.test(spp[[x]]$N15 ~ spp[[x]]$region))  Then you can extract whatever features you want. > out [[1]] Welch Two Sample t-test data: spp[[x]]$N15 by spp[[x]]$region t = -0.7566, df = 2.4628, p-value = 0.515 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: -4.617903 3.018924 sample estimates: mean in group EQ mean in group OMZ 9.982135 10.781625 [[2]] Welch Two Sample t-test data: spp[[x]]$N15 by spp[[x]]\$region
t = 0.66769, df = 3.2858, p-value = 0.5483
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-1.564611  2.448523
sample estimates:
mean in group EQ mean in group OMZ
10.055578          9.613622


Rstatix::t_test() is a user-friendly wrapper of t.test() that returns a tibble.

library(tidyverse)
library(rstatix)

df <- tribble(~species, ~region,  ~N15,
"ARGAFF",    "EQ",  9.85,
"ARGAFF",    "EQ", 10.42,
"ARGAFF",    "EQ", 10.43,
"ARGAFF",   "OMZ", 10.28,
"ARGAFF",   "OMZ", 10.30,
"ARGAFF",   "OMZ", 10.41,
"BATABY",    "EQ", 10.57,
"BATABY",    "EQ", 10.60,
"BATABY",    "EQ", 10.68,
"BATABY",   "OMZ",  9.21,
"BATABY",   "OMZ",  9.29,
"BATABY",   "OMZ",  9.67)
df %>%
group_by(species) %>%
t_test(N15~region)