我们可以在 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)
})
在我下面的 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)
})