我们可以在 R 中为名称创建循环结构吗

Can we create a looping structure for names in R

在我下面的 R 代码中,有太多重复,我理解是不必要的。

我想知道单行(或其他循环结构)是否可以达到完全相同的结果?

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)"

对要更改的 fit 成员使用 lapply 循环。在下面的代码中,行名称在循环中被更改,而列名称不是因为没有重复。

fit 变量的副本被更改,最后与问题的结果进行比较。

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

reprex package (v2.0.1)

于 2022-04-06 创建

或者,使用 {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

reprex package (v2.0.1)

于 2022-04-06 创建

注意:如果你想在函数中重命名colnames,你可以添加:

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)
  })