使用 tidyverse 总结将相同的操作应用于多个列
Applying same operation to several columns using tidyverse summarize
我正在尝试创建一个摘要 table,它为我提供了按年份排序的 17 个问题的肯定回答比例。我只是不知道如何在不硬编码的情况下轻松地将汇总操作应用于多列。
不幸的是,我无法使用 summarize_at 或 summarize_all 函数,因为我正在使用数据框。我正在考虑编写一个函数,循环遍历列,并将摘要列绑定在一起,但是 summarize 对于列名来说有点奇怪,它不能是字符类型。你有什么建议?
这是我目前拥有的:
s2 <- db %>%
group_by(Year)%>%
summarize(Q1=round(sum(Q1d, na.rm=TRUE)*100/length(which(!is.na(Q1d))),1),
Q2=round(sum(Q2d, na.rm=TRUE)*100/length(which(!is.na(Q2d))),1),
Q3=round(sum(Q3d, na.rm=TRUE)*100/length(which(!is.na(Q3d))),1),
Q4=round(sum(Q4d, na.rm=TRUE)*100/length(which(!is.na(Q4d))),1),
Q5=round(sum(Q5d, na.rm=TRUE)*100/length(which(!is.na(Q5d))),1),
Q6=round(sum(Q6d, na.rm=TRUE)*100/length(which(!is.na(Q6d))),1),
Q7=round(sum(Q7d, na.rm=TRUE)*100/length(which(!is.na(Q7d))),1),
Q8=round(sum(Q8d, na.rm=TRUE)*100/length(which(!is.na(Q8d))),1),
Q9=round(sum(Q9d, na.rm=TRUE)*100/length(which(!is.na(Q9d))),1),
Q10=round(sum(Q10d, na.rm=TRUE)*100/length(which(!is.na(Q10d))),1),
Q11=round(sum(Q11d, na.rm=TRUE)*100/length(which(!is.na(Q11d))),1),
Q12=round(sum(Q12d, na.rm=TRUE)*100/length(which(!is.na(Q12d))),1),
Q13=round(sum(Q13d, na.rm=TRUE)*100/length(which(!is.na(Q13d))),1),
Q14=round(sum(Q14d, na.rm=TRUE)*100/length(which(!is.na(Q14d))),1),
Q15=round(sum(Q15d, na.rm=TRUE)*100/length(which(!is.na(Q15d))),1),
Q16=round(sum(Q16d, na.rm=TRUE)*100/length(which(!is.na(Q16d))),1),
Q17=round(sum(Q17d, na.rm=TRUE)*100/length(which(!is.na(Q17d))),1),
)
注意:Q1d、Q2d...是列的名称
我们可以在dplyr
中使用across
library(dplyr)
library(stringr)
db %>%
group_by(Year) %>%
summarise(across(matches('^Q\d+d$'), ~
sum(., na.rm = TRUE) * 100 /sum(!is.na(.))),
.groups = 'drop') %>%
rename_with(~ str_remove(., 'd$'), -Year)
或使用collapse
library(collapse)
f1 <- function(x) sum(x, na.rm = TRUE) * 100/sum(!is.na(x))
collap(db, ~ Year, FUN = f1)
# Year Q1d Q2d
#1 2010 250.0000 350
#2 2015 293.3333 320
数据
db <- data.frame(Year = c(2010, 2010, 2015, 2015, 2015, 2015),
Q1d = c(2.5, NA, 3, 3.5, NA, 2.3), Q2d = c(NA, 3.5, NA, 2, 4.6, 3))
我正在尝试创建一个摘要 table,它为我提供了按年份排序的 17 个问题的肯定回答比例。我只是不知道如何在不硬编码的情况下轻松地将汇总操作应用于多列。
不幸的是,我无法使用 summarize_at 或 summarize_all 函数,因为我正在使用数据框。我正在考虑编写一个函数,循环遍历列,并将摘要列绑定在一起,但是 summarize 对于列名来说有点奇怪,它不能是字符类型。你有什么建议?
这是我目前拥有的:
s2 <- db %>%
group_by(Year)%>%
summarize(Q1=round(sum(Q1d, na.rm=TRUE)*100/length(which(!is.na(Q1d))),1),
Q2=round(sum(Q2d, na.rm=TRUE)*100/length(which(!is.na(Q2d))),1),
Q3=round(sum(Q3d, na.rm=TRUE)*100/length(which(!is.na(Q3d))),1),
Q4=round(sum(Q4d, na.rm=TRUE)*100/length(which(!is.na(Q4d))),1),
Q5=round(sum(Q5d, na.rm=TRUE)*100/length(which(!is.na(Q5d))),1),
Q6=round(sum(Q6d, na.rm=TRUE)*100/length(which(!is.na(Q6d))),1),
Q7=round(sum(Q7d, na.rm=TRUE)*100/length(which(!is.na(Q7d))),1),
Q8=round(sum(Q8d, na.rm=TRUE)*100/length(which(!is.na(Q8d))),1),
Q9=round(sum(Q9d, na.rm=TRUE)*100/length(which(!is.na(Q9d))),1),
Q10=round(sum(Q10d, na.rm=TRUE)*100/length(which(!is.na(Q10d))),1),
Q11=round(sum(Q11d, na.rm=TRUE)*100/length(which(!is.na(Q11d))),1),
Q12=round(sum(Q12d, na.rm=TRUE)*100/length(which(!is.na(Q12d))),1),
Q13=round(sum(Q13d, na.rm=TRUE)*100/length(which(!is.na(Q13d))),1),
Q14=round(sum(Q14d, na.rm=TRUE)*100/length(which(!is.na(Q14d))),1),
Q15=round(sum(Q15d, na.rm=TRUE)*100/length(which(!is.na(Q15d))),1),
Q16=round(sum(Q16d, na.rm=TRUE)*100/length(which(!is.na(Q16d))),1),
Q17=round(sum(Q17d, na.rm=TRUE)*100/length(which(!is.na(Q17d))),1),
)
注意:Q1d、Q2d...是列的名称
我们可以在dplyr
across
library(dplyr)
library(stringr)
db %>%
group_by(Year) %>%
summarise(across(matches('^Q\d+d$'), ~
sum(., na.rm = TRUE) * 100 /sum(!is.na(.))),
.groups = 'drop') %>%
rename_with(~ str_remove(., 'd$'), -Year)
或使用collapse
library(collapse)
f1 <- function(x) sum(x, na.rm = TRUE) * 100/sum(!is.na(x))
collap(db, ~ Year, FUN = f1)
# Year Q1d Q2d
#1 2010 250.0000 350
#2 2015 293.3333 320
数据
db <- data.frame(Year = c(2010, 2010, 2015, 2015, 2015, 2015),
Q1d = c(2.5, NA, 3, 3.5, NA, 2.3), Q2d = c(NA, 3.5, NA, 2, 4.6, 3))