R: Создание нескольких карт с использованием цикла через имена переменных

#r #loops #maps #apply #usmap

Вопрос:

Я хотел бы создать карту, которая показывает значение переменной для данного состояния. Набор данных содержит около тысячи переменных и находится на уровне штата около 100 лет.

Код, который у меня есть и работает, таков:

     plot_usmap(data = database, values = "var1")   scale_fill_continuous(
    low = "white", high = "blue", na.value="light gray", name = "Title of graph", label = scales::comma
  )   theme(legend.position = "right")
 

Теперь я хотел бы создать эту карту для списка примерно из 15 переменных и 10 лет.
Обычно я являюсь пользователем STATA, и там я мог бы определить список переменных, а затем просмотреть список переменных. На странице 7 этого документа «Краткое введение в R (для пользователей Stata)» я попытался применить следующее решение:

 vars <- c("database$var1", "database$var2", "database$var3","database$var4", "database$var5", "database$var6", "database$var7", "database$var8", "database$var9", "database$var10", "database$var11", "database$var12")
for(var in vars) {
  v <- get(var)
  plot_usmap(data = darabase, values = "v")   
    scale_fill_continuous(low = "white", high = "blue", na.value="light gray", name = "v", label = scales::comma)   theme(legend.position = "right")}
 

С помощью этого кода я получаю ошибку «Ошибка в get(var) : объект «база данных$var1» не найден. Когда я пытаюсь просмотреть(база данных$var1), он появляется. Следующая проблема заключается в том, что я хотел бы, чтобы имя графика было меткой переменной, а не переменной. В приведенном выше примере я ограничил все данные только 1 годом, поэтому, если есть решение для настройки кода, чтобы я мог использовать всю базу данных, но сопоставлять только выбранные годы, это было бы здорово.

Любые идеи будут оценены по достоинству! Я читал, что в R «для» используется не так часто, поэтому, если есть лучший способ сделать это, пожалуйста, дайте мне знать.

Ответ №1:

В принципе, это не так уж отличается от R. Во-первых, нет необходимости использовать get и вообще следует избегать. Во-вторых, в то время как для петель все в порядке, тем более правильным способом было бы их использовать lapply . Особенно ggplot2 рекомендуется использовать при составлении графиков с помощью lapply .

Использование некоторых поддельных примеров данных для имитации database :

 library(usmap)
library(ggplot2)

# Example data
database <- statepop
names(database) <- c("fips", "abbr", "full", "var1")
database$var2 <- database$var1

vars <- c("var1", "var2")

lapply(vars, function(x) {
  plot_usmap(data = database, values = x)   
    scale_fill_continuous(
    low = "white", high = "blue", na.value="light gray", name = "Title of graph", label = scales::comma
  )   
    theme(legend.position = "right")  
    labs(title = x)
})
#> [[1]]
 

 #> 
#> [[2]]
 

РЕДАКТИРОВАТЬ Предполагая, что ваши данные содержат столбец с годами, я бы предложил обернуть код построения внутри функции, которая принимает вашу базу данных, набор переменных и желаемый год в качестве аргумента. Но есть и другие подходы, и то, что работает лучше, зависит от вашего желаемого результата.

 library(usmap)
library(ggplot2)
library(labelled)

# Example data
database <- statepop
names(database) <- c("fips", "abbr", "full", "var1")
database$year <- 2015
database <- rbind(database, transform(database, year = 2020))
var_label(database$var1) <- "Population"

vars <- c("var1")
names(vars) <- vars

map_vars <- function(.data, vars, year) {
  lapply(vars, function(x, year) {
    .data <- .data[.data$year == year, ]
    plot_usmap(data = database, values = x)  
      scale_fill_continuous(
        low = "white", high = "blue", na.value = "light gray", name = "Title of graph", label = scales::comma
      )  
      theme(legend.position = "right")  
      labs(title = paste(var_label(database[[x]]), "in", year))
  }, year = year)  
}

map_vars(database, vars, 2015)
#> $var1
 

 map_vars(database, vars, 2020)
#> $var1
 

Комментарии:

1. Спасибо! Это сработало. Знаете ли вы, как бы я изменил название карты, чтобы оно соответствовало метке переменной, а не имени переменной? Например, « библиотека(помечена) var_label(statepop$pop_2015) Например, я мог бы представить себе определение списка меток переменных и списка лет, но, похоже, у lapply нет возможности для вложенности.

2. Привет, Пьер. Первый вопрос прост. Если ваши данные уже помечены, вы можете labs(title = labelled::var_label(database[[x]])) добавить метку переменной в качестве заголовка. Кроме того, помимо lapply существует также mapply, который позволяет перебирать несколько списков. Наконец, я просто внес правку, чтобы показать один подход, когда ваши данные содержат несколько слов и как добавить их в заголовок.