Я пытаюсь создать цикл или функцию для набора данных ниже.
Для общего_здоровья, мировоззрения_жизни и здоровья_психического я пытаюсь рассчитать соотношение по полу, возрастной группе, доходу и образованию. Кроме того, я хотел бы создать два отдельных выхода по географии (область1 и область2).
Обратите внимание, что я не хочу использовать функцию поворота дольше.
Заранее спасибо за помощь!
Вот пример кадра данных (данные опроса):
library(tidyverse)
library(dplyr)
df <- data.frame (overall_health = c("poor", "good", "excellent", "poor", "good", "poor", "poor", "excellent"),
outlook_life = c("good", "excellent", "excellent", "poor", "excellent", "poor", "excellent", "poor"),
health_mental = c("poor", "poor", "excellent", "poor", "poor", "poor", "excellent", "good"),
sex = c("F", "M", "M", "F", "F", "M", "F", "M"),
age_group = c("50-54", "60-64", "80+", "70-74", "40-44", "45-49", "60-64", "65-69"),
income = c("$<40,000", "$50,000-79,000", "$80,000-110,000", "$111,000+", "$<40,000", "$<40,000", "$50,000-79,000", "$80,000-110,000"),
education = c("HS", "College", "Bachelors", "Masters", "HS", "College", "Bachelors", "Masters"),
geography= c("area1", "area2", "area1", "area2", "area2", "area1", "area2", "area1"))
Как правило, можно рассчитать пропорцию по возрастным группам следующим образом:
df_new <- df %>%
group_by(overall_health, age_group, geography) %>%
summarise(count = n(),
total = 8,
proportion = count/total *100)
Однако я хотел бы создать цикл/функцию для расчета этих частей для total_health, outlook_life и health_mental по: возрастной группе, полу, доходу, образованию (в географии = «область1») Я хотел бы сделать то же самое или geography="area 2".
Таким образом, для total_health, outlook_life и health_mental у меня будет несколько выходных данных по возрастной группе, полу, доходу, образованию, которые выглядят следующим образом:
общее_здоровье x возрастная_группа
Outlook_life x возрастная_группа
здоровье_психическое x возрастная_группа
общее_здоровье x пол
library(tidyverse)
## unique geographies:
geos <- unique(df$geography)
## You can input combinations to a list to iterate over and label accordingly.
vars <- c("health_mental", "overall_health", "outlook_life")
## expand.grid will create every possible combination between the two vectors you supply it:
combinations <- expand.grid(c("age_group", "sex"), vars, stringsAsFactors = F)
combinations$label <- paste(combinations$Var1, combinations$Var2, sep = "_")
## list to output dataframe results to:
output <- list()
## Outer for loop will iterate through each of your geographies.
for (geo in geos){
## Inner loop will iterate through each of your combinations
for (combo in 1:nrow(combinations)){
## outputs are labelled based on combination + geo and stored in output list.
output_label <- paste(combinations[[combo,"label"]],geo,sep = "_")
temp <- df %>%
filter(geography == geo) %>%
group_by_at(combinations[combo,1:2] %>% unlist()%>%unname()) %>%
summarise(count = n(),
total = nrow(.),
proportion = count/nrow(.) *100)
output[[output_label]] <- temp
# You could also export each csv iteratively, with proper labelling automatically as well:
#write.csv(temp, paste0("insert_file_path", output_label, ".csv"))
}
}
Доступ к кадрам данных можно получить через списки по их метке списка:
## all dataframes:
output
## Overall Health x Age Group for Area 1:
output$overall_health_x_age_group_area1
## or
output[["overall_health_x_age_group_area1"]]
Только что модифицировал! вам просто нужно ввести уникальные переменные, которые вы хотите сравнить с «возрастом» и «полом», в вектор vars. Вы можете сделать это проще, если просто подмножите имена столбцов в своем фрейме данных и передадите их также в vars.
Большое спасибо, это действительно полезно. Одна дилемма, которая у меня все еще есть, заключается в том, что у меня есть много переменных, помимо общего_здоровья, здоровья_психического, мировоззрения_жизни. Есть ли способ оптимизировать скрипт для циклического просмотра множества столбцов?