How to create a loop over multiple columns for the clusWilcox.test function

Viewed 38

For my data analysis, I need to run clusWilcox.test (clusrank package) for multiple columns in my dataset. This dataset consists of 92 columns, of which colums 1 to 26 are possible independent variables (all factors), and 27 to 92 are dependent variables (all numeric) that I want to test.

If I were to do all the tests manually, it should look like:

clusWilcox.test(column27 ~ treatment + cluster(factor1), data = df)
clusWilcox.test(column28 ~ treatment + cluster(factor1), data = df)

...

clusWilcox.test(column92 ~ treatment + cluster(factor1), data = df)

I though it should be possible to make R do these subsequent test automatically and then give me the output for all these tests at once. I found a code for using the lapply function for a linear model (lm function) that I tried to adapt to the clusWilcox.test, however this does not work.

This is de code I found:

names(df)
varlist <- names(df)[27:92]
models <- lapply(varlist, function(x) {
  lm(substitute(i ~ treatment + factor1, list(i = as.name(x))), data = df)
})
models

This works perfectly for my dataset. So my next step was to adapt this code, as I need to run the clusWilcox.test instead of a lm. I adapted the code as follows:

names(df)
varlist <- names(df)[27:92]
models2 <- lapply(varlist, function(x) {
  clusWilcox.test(substitute(i ~ treatment + cluster(factor1), list(i = as.name(x))), data = df)
})
models2

However, this code gives the following error message:

Error in `vectbl_as_col_location()`:
! Can't subset columns that don't exist.
✖ Columns `substitute`, `i ~ Treatment`, and `list(i = as.name(x))` don't exist.
Run `rlang::last_error()` to see where the error occurred.
> rlang::last_error()
<error/vctrs_error_subscript_oob>
Error in `vectbl_as_col_location()`:
! Can't subset columns that don't exist.
✖ Columns `substitute`, `i ~ Treatment`, and `list(i = as.name(x))` don't exist.
---
Backtrace:
 1. base::lapply(...)
 2. global FUN(X[[i]], ...)
 4. clusrank:::clusWilcox.test.default(...)
 5. clusrank:::extractVar("x", pars, data)
 7. tibble:::`[.tbl_df`(data, , as.character(pars[[var]]))
 8. tibble:::vectbl_as_col_location(j, length(x), names(x), j_arg = j_arg, assign = FALSE)
Run `rlang::last_trace()` to see the full context.
> 
> rlang::last_trace()
<error/vctrs_error_subscript_oob>
Error in `vectbl_as_col_location()`:
! Can't subset columns that don't exist.
✖ Columns `substitute`, `i ~ Treatment`, and `list(i = as.name(x))` don't exist.
---
Backtrace:
     ▆
  1. └─base::lapply(...)
  2.   └─global FUN(X[[i]], ...)
  3.     ├─clusrank::clusWilcox.test(...)
  4.     └─clusrank:::clusWilcox.test.default(...)
  5.       └─clusrank:::extractVar("x", pars, data)
  6.         ├─data[, as.character(pars[[var]])]
  7.         └─tibble:::`[.tbl_df`(data, , as.character(pars[[var]]))
  8.           └─tibble:::vectbl_as_col_location(j, length(x), names(x), j_arg = j_arg, assign = FALSE)
  9.             ├─tibble:::subclass_col_index_errors(...)
 10.             │ └─base::withCallingHandlers(...)
 11.             └─vctrs::vec_as_location(j, n, names)
 12.               └─vctrs (local) `<fn>`()
 13.                 └─vctrs:::stop_subscript_oob(...)
 14.                   └─vctrs:::stop_subscript(...)
 15.                     └─rlang::abort(...)

What did I do wrong, and how I can let R repeat the test multiple times over all the columns?

1 Answers

Convert to formula class:

library(clusrank)

#example data
df <- mtcars[, c("vs", "am", "mpg")]
names(df)
# [1] "vs"  "am"  "mpg"

varlist <- names(df)[1:2]
# [1] "vs" "am"

lapply(varlist, function(x) {
  clusWilcox.test(as.formula(substitute(mpg ~ i, list(i = as.name(x)))), data = df)
})

#[[1]]
#
#   Clustered Wilcoxon rank sum test using Rosner-Glynn-Lee method
#
#data:  mpg; group: vs; (from df)
#number of observations: 32;  number of clusters: 32
#Z = 3.9342, p-value = 8.349e-05
#alternative hypothesis: true difference in locations is not equal to 0
#
#
#[[2]]
#
#   Clustered Wilcoxon rank sum test using Rosner-Glynn-Lee method
#
#data:  mpg; group: am; (from df)
#number of observations: 32;  number of clusters: 32
#Z = 3.1291, p-value = 0.001753
#alternative hypothesis: true difference in locations is not equal to 0

Alternatively, I prefer to use paste to construct the formula:

lapply(varlist, function(x) {
  f <- as.formula(paste("mpg ~", x))
  clusWilcox.test(f, data = df)
})
Related