Home > other >  Can we create a looping structure for names in R
Can we create a looping structure for names in R

Time:04-07

In my R code below, there is so much repetition that I understand is unnecessary.

I was wondering if possibly a one-liner (or other looping structure) can achieve the exact same result?

library(metafor)

fit <- rma(yi~factor(grade),vi,data=dat.bangertdrowns2004)

rownames(fit$b)[rownames(fit$b) %in% "intrcpt"] <- "(Intercept)"
rownames(fit$beta)[rownames(fit$beta) %in% "intrcpt"] <- "(Intercept)"
rownames(fit$vb)[rownames(fit$vb) %in% "intrcpt"] <- "(Intercept)"
colnames(fit$vb)[colnames(fit$vb) %in% "intrcpt"] <- "(Intercept)"

CodePudding user response:

Use a lapply loop over the fit members you want to change. In the code below the row names are changed in a loop, and the column names not because there's no repetition.

A copy of the fit variable is changed and in the end compared to the question's result.

suppressPackageStartupMessages(
  library(metafor)
)

fit <- rma(yi~factor(grade),vi,data=dat.bangertdrowns2004)
fit2 <- fit

list_elems <- c("b", "beta", "vb")
fit2[list_elems] <- lapply(fit2[list_elems], \(x) {
  rownames(x)[rownames(x) %in% "intrcpt"] <- "(Intercept)"
  x
})
colnames(fit2$vb)[colnames(fit2$vb) %in% "intrcpt"] <- "(Intercept)"

rownames(fit$b)[rownames(fit$b) %in% "intrcpt"] <- "(Intercept)"
rownames(fit$beta)[rownames(fit$beta) %in% "intrcpt"] <- "(Intercept)"
rownames(fit$vb)[rownames(fit$vb) %in% "intrcpt"] <- "(Intercept)"
colnames(fit$vb)[colnames(fit$vb) %in% "intrcpt"] <- "(Intercept)"

identical(fit, fit2)
#> [1] TRUE

Created on 2022-04-06 by the reprex package (v2.0.1)

CodePudding user response:

Alternatively, using {tidyverse}:

library(dplyr)
library(metafor)

fit <- rma(yi~factor(grade),vi,data=dat.bangertdrowns2004)

fit2 <- fit %>%
  purrr::map_at(c("b", "beta", "vb"), function(x) {
   rownames(x)[rownames(x) %in% "intrcpt"] <- "(Intercept)"
   return(x)
  })

colnames(fit2$vb)[colnames(fit2$vb) %in% "intrcpt"] <- "(Intercept)"

fit2[c("b", "beta", "vb")]
#> $b
#>                       [,1]
#> (Intercept)     0.26390547
#> factor(grade)2 -0.37269264
#> factor(grade)3  0.02484665
#> factor(grade)4 -0.01552720
#> 
#> $beta
#>                       [,1]
#> (Intercept)     0.26390547
#> factor(grade)2 -0.37269264
#> factor(grade)3  0.02484665
#> factor(grade)4 -0.01552720
#> 
#> $vb
#>                 (Intercept) factor(grade)2 factor(grade)3 factor(grade)4
#> (Intercept)     0.008061379   -0.008061379   -0.008061379   -0.008061379
#> factor(grade)2 -0.008061379    0.029076616    0.008061379    0.008061379
#> factor(grade)3 -0.008061379    0.008061379    0.018612667    0.008061379
#> factor(grade)4 -0.008061379    0.008061379    0.008061379    0.013458160

Created on 2022-04-06 by the reprex package (v2.0.1)

Note: If you want the colnames renaming in the function you can add this:

fit2 <- fit %>%
  purrr::map_at(c("b", "beta", "vb"), function(x) {
    rownames(x)[rownames(x) %in% "intrcpt"] <- "(Intercept)"

    if ("intrcpt" %in% colnames(x)) {
      colnames(x)[colnames(x) %in% "intrcpt"] <- "(Intercept)"
    }

    return(x)
  })
  • Related