按名称循环 R 中的变量子集
looping over a subset of variables in R by name
数据框have
包含几千个变量。一个变量是称为 treatgrp
的治疗指标,它包含值 1、2 或 3)。其他五个变量称为:g_cA
、r_cA
、g_ccA
、r_ccA
和 g_grp
。它们没有按顺序出现。
我想生成 tables 的频率,将 treatgrp
与其他五个感兴趣的变量进行比较。我目前使用一些墙纸语法来这样做:
table(have$treatgrp, have$g_cA, deparse.level = 2)
table(have$treatgrp, have$r_cA, deparse.level = 2)
table(have$treatgrp, have$g_ccA, deparse.level = 2)
table(have$treatgrp, have$r_ccA, deparse.level = 2)
table(have$treatgrp, have$g_grp, deparse.level = 2)
这样就可以了。但我想调用 table()
一次并迭代感兴趣的五个不同变量。我尝试这样做:
myvars <- c("g_cA", "r_cA", "g_ccA", "r_ccA", "g_grp")
for (i in 1:length(myvars)){
table(have$treatgrp, have[,myvars[i]], deparse.level = 2)
}
这不会产生错误消息,但也会 returns 没有输出 table。
根据这个问题,我可能很明显已经习惯了 SAS 中的宏和数组。但我想至少学习一种方法来解决这个问题。我必须一直做类似的事情,找出一个更优雅的解决方案会节省我很多时间。
我想到的一个解决方案:
创建一个较小的数据框,其中包含 have
中感兴趣的变量,并遍历索引
have_mini <- have[,c("treatgrp","g_cA", "r_cA", "g_ccA", "r_ccA", "g_grp")]
然后参考have_mini
的索引
for (i in 2:length(have_mini)){
table(have_mini[,1], have_mini[,i], deparse.level = 2)
}
但我仍在对此进行调试:即使我没有收到错误,似乎也没有打印任何内容。最重要的是,我确信还有一种我不知道的更好的方法。
以 iris
数据集为例,使用 lapply
是否可行?
iris$var1 <- sample(letters, 150, replace = T)
iris$var2 <- sample(letters, 150, replace = T)
iris$var3 <- sample(letters, 150, replace = T)
myvars <- c("var1", "var2", "var3")
lapply(iris[myvars], function(x) table(iris$Species, x))
# $var1
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 1 1 0 3 2 2 0 1 2 4 2 1 1 4 3 1 4 0 3 0 4 3 3 2 0 3
# versicolor 3 1 2 3 0 4 1 3 5 0 1 0 1 3 5 2 2 1 5 1 2 0 1 1 1 2
# virginica 4 0 1 1 3 4 2 1 2 1 2 4 1 1 1 2 2 2 3 3 0 2 2 2 3 1
# $var2
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 3 1 1 3 3 3 2 2 2 2 1 1 2 1 0 4 1 2 2 4 4 3 2 0 1 0
# versicolor 3 0 1 1 5 3 3 3 2 2 1 2 2 4 1 4 2 3 2 0 2 1 2 1 0 0
# virginica 0 2 1 4 3 0 0 1 1 0 4 2 3 2 1 2 0 3 2 2 2 0 2 2 5 6
# $var3
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 4 2 4 2 0 4 0 3 3 2 0 1 2 0 0 2 1 3 2 1 1 2 2 1 5 3
# versicolor 0 3 1 3 1 1 1 0 1 1 3 2 1 0 0 4 4 1 3 6 2 2 2 3 2 3
# virginica 3 0 3 3 2 0 3 1 1 2 0 2 4 4 1 4 1 3 4 0 1 1 2 3 2 0
或使用 purrr::map
同样的事情:
library(purrr)
map(iris[myvars], function(x) table(iris$Species, x))
在循环中你需要使用 print()。
data <- data.frame("id" = c(1:12), "treatment" = c(1, 2, 3),
"v1" = c("a", "b"),
"v2" = c("X", "Y", "Z"))
vars <- c("v1", "v2")
for (i in 1:length(vars)) {
t <- table(data[,vars[i]], data$treatment)
print(t)
}
数据框have
包含几千个变量。一个变量是称为 treatgrp
的治疗指标,它包含值 1、2 或 3)。其他五个变量称为:g_cA
、r_cA
、g_ccA
、r_ccA
和 g_grp
。它们没有按顺序出现。
我想生成 tables 的频率,将 treatgrp
与其他五个感兴趣的变量进行比较。我目前使用一些墙纸语法来这样做:
table(have$treatgrp, have$g_cA, deparse.level = 2)
table(have$treatgrp, have$r_cA, deparse.level = 2)
table(have$treatgrp, have$g_ccA, deparse.level = 2)
table(have$treatgrp, have$r_ccA, deparse.level = 2)
table(have$treatgrp, have$g_grp, deparse.level = 2)
这样就可以了。但我想调用 table()
一次并迭代感兴趣的五个不同变量。我尝试这样做:
myvars <- c("g_cA", "r_cA", "g_ccA", "r_ccA", "g_grp")
for (i in 1:length(myvars)){
table(have$treatgrp, have[,myvars[i]], deparse.level = 2)
}
这不会产生错误消息,但也会 returns 没有输出 table。
根据这个问题,我可能很明显已经习惯了 SAS 中的宏和数组。但我想至少学习一种方法来解决这个问题。我必须一直做类似的事情,找出一个更优雅的解决方案会节省我很多时间。
我想到的一个解决方案:
创建一个较小的数据框,其中包含 have
中感兴趣的变量,并遍历索引
have_mini <- have[,c("treatgrp","g_cA", "r_cA", "g_ccA", "r_ccA", "g_grp")]
然后参考have_mini
for (i in 2:length(have_mini)){
table(have_mini[,1], have_mini[,i], deparse.level = 2)
}
但我仍在对此进行调试:即使我没有收到错误,似乎也没有打印任何内容。最重要的是,我确信还有一种我不知道的更好的方法。
以 iris
数据集为例,使用 lapply
是否可行?
iris$var1 <- sample(letters, 150, replace = T)
iris$var2 <- sample(letters, 150, replace = T)
iris$var3 <- sample(letters, 150, replace = T)
myvars <- c("var1", "var2", "var3")
lapply(iris[myvars], function(x) table(iris$Species, x))
# $var1
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 1 1 0 3 2 2 0 1 2 4 2 1 1 4 3 1 4 0 3 0 4 3 3 2 0 3
# versicolor 3 1 2 3 0 4 1 3 5 0 1 0 1 3 5 2 2 1 5 1 2 0 1 1 1 2
# virginica 4 0 1 1 3 4 2 1 2 1 2 4 1 1 1 2 2 2 3 3 0 2 2 2 3 1
# $var2
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 3 1 1 3 3 3 2 2 2 2 1 1 2 1 0 4 1 2 2 4 4 3 2 0 1 0
# versicolor 3 0 1 1 5 3 3 3 2 2 1 2 2 4 1 4 2 3 2 0 2 1 2 1 0 0
# virginica 0 2 1 4 3 0 0 1 1 0 4 2 3 2 1 2 0 3 2 2 2 0 2 2 5 6
# $var3
# x
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# setosa 4 2 4 2 0 4 0 3 3 2 0 1 2 0 0 2 1 3 2 1 1 2 2 1 5 3
# versicolor 0 3 1 3 1 1 1 0 1 1 3 2 1 0 0 4 4 1 3 6 2 2 2 3 2 3
# virginica 3 0 3 3 2 0 3 1 1 2 0 2 4 4 1 4 1 3 4 0 1 1 2 3 2 0
或使用 purrr::map
同样的事情:
library(purrr)
map(iris[myvars], function(x) table(iris$Species, x))
在循环中你需要使用 print()。
data <- data.frame("id" = c(1:12), "treatment" = c(1, 2, 3),
"v1" = c("a", "b"),
"v2" = c("X", "Y", "Z"))
vars <- c("v1", "v2")
for (i in 1:length(vars)) {
t <- table(data[,vars[i]], data$treatment)
print(t)
}