如何解决R、dplyr:使用动态变量访问表名
我正在尝试在 for 循环中使用动态变量来访问表名。关于 SO 的其他问题(例如 here、here 和 here)似乎与使用动态变量访问列名有关。我使用的是 R v4.0.3 和 dplyr v1.0.2。
基本上,我从 .sav (SPSS) 文件导入,并试图将 400 多列拆分为包含每个调查问题信息的较小数据框。这部分有效,但我随后想做一些事情,例如为每个新数据框添加一个均值列。我目前正在尝试在分段 for 循环中执行此操作,但无法使其正常工作。 (我也很乐意为另一个 for 循环或列表或其他东西中的每个新数据帧分别执行此操作,但如果我无法让另一个数据帧工作,我也看不出这将如何工作!)
稍微简化一下,原始文件中的列被命名为 QX.Y_Z,其中 Z 是 X 块中问题 Y 中的项目。
一些虚拟数据,设置一个(sav-type)数据框,包含 2 个问题,每个问题有两个项目:
mydata=tibble(Q6.1_1_1=as.numeric(c(2,1,3,2,2)),Q6.1_1_2=as.numeric(c(1,Q7.1_1_1=as.numeric(c(1,Q7.1_1_2=as.numeric(c(3,3)),)
var_label(mydata$Q6.1_1_1)<-"Rate your effort - before."
var_label(mydata$Q6.1_1_2)<-"Rate your effort - before."
var_label(mydata$Q7.1_1_1)<-"Rate your enthusiasm - before."
var_label(mydata$Q7.1_1_2)<-"Rate your enthusiasm - after."
val_labels(mydata$Q6.1_1_1)<-c(Low=1,Medium=2,High=3)
val_labels(mydata$Q6.1_1_2)<-c(Low=1,High=3)
val_labels(mydata$Q7.1_1_1)<-c(Low=1,High=3)
val_labels(mydata$Q7.1_1_2)<-c(Low=1,High=3)
mydata
# A tibble: 14 x 4
Q6.1_1_1 Q6.1_1_2 Q7.1_1_1 Q7.1_1_2
<dbl+lbl> <dbl+lbl> <dbl+lbl> <dbl+lbl>
1 2 [Medium] 1 [Low] 1 [Low] 3 [High]
2 1 [Low] 3 [High] 2 [Medium] 1 [Low]
3 3 [High] 1 [Low] 1 [Low] 3 [High]
4 1 [Low] 1 [Low] 2 [Medium] 1 [Low]
5 2 [Medium] 1 [Low] 1 [Low] 2 [Medium]
6 3 [High] 2 [Medium] 3 [High] 1 [Low]
7 1 [Low] 3 [High] 3 [High] 3 [High]
8 3 [High] 3 [High] 1 [Low] 2 [Medium]
9 2 [Medium] 1 [Low] 2 [Medium] 3 [High]
10 1 [Low] 3 [High] 3 [High] 1 [Low]
11 1 [Low] 1 [Low] 2 [Medium] 3 [High]
12 1 [Low] 1 [Low] 1 [Low] 1 [Low]
13 2 [Medium] 1 [Low] 3 [High] 1 [Low]
14 2 [Medium] 2 [Medium] 2 [Medium] 3 [High]
从问题字符串中删除项目编号:
varlist<-mydata %>%
colnames() %>%
as_tibble() %>%
separate(value,"qno",sep="_",extra = "drop",fill="right") %>%
unique() %>%
pull()
> varlist
[1] "Q6.1" "Q7.1"
生成子表:
for (v in varlist) {
assign(paste0("table",v),select(mydata,matches(v)))
}
这给了我名为 tableQ6.1 和 tableQ7.1 的子表。到目前为止,一切都很好。
但是,当我尝试在生成这些子表时为每个子表添加一个均值列(给出每行的均值)时,我找不到告诉 mutate() 使用动态名称的方法桌子。这些是我尝试过的几个选项,但我得到的(包括这些和更多)是错误,所以我一定遗漏了一些明显的东西:
for (v in varlist) {
assign(paste0("table",matches(v)))
tabname<-sym(paste0("table",v))
mutate({{tabname}},mean=rowMeans(across(where(is.numeric)),na.rm = FALSE))
}
for (v in varlist) {
assign(paste0("table",matches(v)))
tabname<-"table{v}" %>%
mutate("mean{v}":=rowMeans(across(where(is.numeric)),na.rm = FALSE))
}
解决方法
您可以使用 split.default
拆分具有相似列名的数据框,然后对每个子集取行均值。这将避免您创建中间数据框和变量。
sapply(split.default(mydata,sub('\\..*','',names(mydata))),rowMeans)
# Q6 Q7
# [1,] 1.5 2.0
# [2,] 2.0 1.5
# [3,] 2.0 2.0
# [4,] 1.0 1.5
# [5,] 1.5 1.5
# [6,] 2.5 2.0
# [7,] 2.0 3.0
# [8,] 3.0 1.5
# [9,] 1.5 2.5
#[10,] 2.0 2.0
#[11,] 1.0 2.5
#[12,] 1.0 1.0
#[13,] 1.5 2.0
#[14,] 2.0 2.5
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。