ltw
ltw

Reputation: 285

R - using apply on numeric matrix with shapiro.test() gives error: all 'x' values are identical

I have a data.frame df with > 110 000 rows. It looks like that:

  traking_id         A1_CTRL     A2_CTRL     A3_CTRL     A4_CTRL     A5_CTRL     A1_DEX      A2_DEX      A3_DEX      A4_DEX      A5_DEX
1 ENSMUST00000000001 1.35358e+01 1.03390e+01 1.03016e+01 1.12654e+01 1.22707e+01 1.40684e+01 9.15279e+00 1.17276e+01 1.14550e+01 1.46256e+01
2 ENSMUST00000000003 5.01868e-06 5.59107e-06 1.60922e-01 2.45402e-01 2.18614e-01 2.24124e-01 2.88035e-01 7.18876e-06 1.74746e-06 0.00000e+00
...

I'm interested in perform shapiro.test twice for each row - once for values in columns 2:6, an once for values in columns 7:11.

I want to obtain two lists of objects that function shapiro.test returns in order to extract from them p.value column. I want to do it by using function apply, but my code

shapiro.test_CTRL <- apply(data.matrix(df[,2:6]), 1, shapiro.test)

returns an error

Error in FUN(newX[, i], ...) : all 'x' values are identical

However, when I use pearson.test everything works fine:

pearson.test_CTRL <- apply(data.matrix(df[,2:6]), 1, pearson.test)

Calculating shapiro.test just for one row also works fine:

shapiro.test(data.matrix(x[1,2:6]))

I would like to know why using apply with shapiro.test the way I did resulted in error and how to correctly do it?

Upvotes: 2

Views: 3386

Answers (1)

Zelazny7
Zelazny7

Reputation: 40628

If you look at the source for shapiro.test it has this line:

...
        x <- sort(x[complete.cases(x)])
        n <- length(x)
        if (is.na(n) || n < 3L || n > 5000L) 
            stop("sample size must be between 3 and 5000")
        rng <- x[n] - x[1L]
        if (rng == 0) 
            stop("all 'x' values are identical")
...

This error is triggered the values of your row are all the same. The same error can be triggered with this code:

mtcars[2,] <- 1
apply(mtcars[,2:5], 1, shapiro.test)

You can avoid this error by testing for that condition and returning something else:

f <- function(x) {
  if (diff(range(x)) == 0) list() else shapiro.test(x)
}

apply(mtcars[,2:5], 1, f)

Upvotes: 2

Related Questions