Использование map (purrr) для перебора двух векторов в R - PullRequest
2 голосов
/ 13 марта 2020

Я пытаюсь построить карты для трех различных зависимых переменных (каждая из которых представлена ​​отдельно) в нескольких зонах метро. Для этого я пытаюсь сделать 2 вложенные карты. Я начинаю с того, что делаю это только над 3 различными переменными для одной области метро - определяя функцию и проводя ее по карте, и она работает. Код для этой части ниже:

plot_fun <- function(x){
  base_plot_2015$`14460` +
  data_2015 %>% subset(met2013 == 14460) %>% subset(onetsoccode == "151021") %>% 
    geom_sf(mapping = aes_string(fill = x)) +
    scale_fill_viridis_c(option = "plasma") 
}

expl <- names(data_2015)[17:19]
expl <- set_names(expl)

plot_Boston <- map(expl, ~plot_fun(.x))

Это дает мне список из 3 карт и пока все хорошо. (Обратите внимание, что base_plot - это список, содержащий карты каждой из областей метро, ​​сохраненных как идентификатор области метро, ​​который хранится как двойной).

Далее я хочу сделать то же самое, но и повторять его по разным кодам метро. Я пытаюсь сделать это, определив следующую функцию:

plot_fun <- function(x,y){
  base_plot_2015$`y` +
    data_2015 %>% subset(met2013 == y) %>% subset(onetsoccode == "151021") %>% 
    geom_sf(mapping = aes_string(fill = x)) +
    scale_fill_viridis_c(option = "plasma") 
}

Идея состоит в том, чтобы сопоставить ее с вектором областей метрополитена (y) для каждой зависимой переменной, которая будет построена (x). Однако, прежде чем я это сделаю, я не могу заставить эту функцию работать. Когда я запускаю эту функцию, используя plot_fun("work_home", 14460), я получаю следующую ошибку:

Ошибка в base_plot_2015 $ y + data_2015%>% subset (met2013 == y)%>% subset (onetsoccode == : non-Numberri c аргумент бинарного оператора

Может быть, кто-то будет достаточно любезен, чтобы указать, что я здесь делаю неправильно?

Кроме того, для выполнения вложенной карты код map(met, ~map(expl, ~plot_fun, y=.x)) (где встречается вектор кодов городов метрополитена) имеет смысл?

1 Ответ

1 голос
/ 14 марта 2020

TLDR: когда вы поднастраиваете свой список base_plot, вам нужно использовать оператор [[ вместо $

Во второй версии функция воспринимает ее как "y" строку, а не переменная y. Так как, по-видимому, нет никакого метро-кода "y", возвращается NULL. Двоичный оператор - +, а NULL не является числом c. Вот упрощенный пример того, что происходит:

base_data <- list(
  a = letters,
  b = LETTERS,
  c = rnorm(100)
)

getMyData <- function(y){
  base_data$`x`
} 

getMyData("a")
#> NULL

base_data$x <- "QSBjbHVlIHBlcmhhcHM="

val <- getMyData("a") %>% print()
#> [1] "QSBjbHVlIHBlcmhhcHM="

base64enc::base64decode(val) %>% rawToChar()
#> [1] "A clue perhaps"

Если вы измените свою функцию на использование оператора [[, вы можете использовать строковое значение в переменной y для подмножества:

actuallyGetMyData <- function(x){
  base_data[[x]]
}

actuallyGetMyData("a")[1:10]
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

РЕДАКТИРОВАТЬ : Относительно сопоставления перестановок (потому что трудно читать код в комментариях)

вызов map(expl, ~plot_fun) создает анонимную функцию, которая возвращает функцию plot_fun , Вам нужно либо удалить анонимную функцию

map(met, ~map(expl, plot_fun, y=.x))

, либо вызвать функцию

map(met, ~map(expl, ~plot_fun(.x, .y), .y=.x))

Я считаю, что вложенные карты немного трудно читать (.x становится .y, а что нет) так что в качестве альтернативы вы можете сначала перечислить все комбинации, а затем отобразить их

plotVars <- expand.grid(expl, met)
plot_final <- map2(plotVars[[1]], plotsVars[[2]],  plot_fun) %>% 
  set_names(paste(plotVars[[1]], plotVars[[2]], sep = "_"))

Обратите внимание, что ваш список plot_final больше не будет вложенным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...