使用 for 循环创建多个图
Using a for loop to create multiple plots
我是使用循环和简化代码的新手。
我有一个地点数据集,其中包含我想在单独地图上绘制的随附数据。我可以单独绘制地图。
但是我想稍微自动化这个过程,我每天都有新数据到达,不想重复清理数据和重写代码的过程。
所以我认为 for
循环可能就是答案
我需要的是下面数据中每个 Time
的单独图
所以循环会提取每个 Time
值的所有数据,然后绘制它。
dput(df)
structure(list(Site = c("O242", "O51", "O59", "O71", "C110",
"C116", "C120", "C13", "C132", "C134", "C139", "C140", "C29",
"C30", "C33", "C48", "C56", "C9A", "MP25", "MP67", "B30", "MP2",
"B101", "B11", "B112", "B15", "B197", "B2", "B217", "B22", "B30",
"B95", "MP21", "MP25", "MP33", "MP51", "MP56", "MP6", "MP60",
"MP61", "MP67", "MP77", "EX84", "EX92", "SW130", "O31", "O38",
"O38B", "O48", "O58", "O59", "O68", "O71", "O72", "O81", "O94",
"O207", "O209", "O210", "O215"), Time = c(-25, -22, -22, -22,
-14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-14, -23, -23, -20, -20, -11, -11, -11, -11, -11, -11, -11, -11,
-11, -11, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
-10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
-10, -10, -10, -10), Code = c(1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L,
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 3L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 3L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L,
1L, 1L, 1L, 2L, 1L, 2L, 1L, 3L, 2L, 1L, 3L, 1L, 1L, 3L, 2L, 2L,
3L, 1L, 1L, 2L), lon = c(-1.341280663, -1.343562025, -1.343620358,
-1.340629756, -1.332551665, -1.329108814, -1.328655294, -1.330835311,
-1.330715028, -1.33052464, -1.328144549, -1.328287425, -1.329353862,
-1.329343236, -1.33041446, -1.325353001, -1.327279282, -1.332909331,
-1.300122834, -1.299148682, -1.310197641, -1.305886812, -1.308725397,
-1.309505208, -1.309235075, -1.308580716, -1.30959055, -1.308685087,
-1.309426224, -1.306562029, -1.310197641, -1.307564253, -1.301598673,
-1.300122834, -1.299510666, -1.299846899, -1.297823339, -1.305388627,
-1.297220016, -1.297398331, -1.299148682, -1.300378324, -1.333554619,
-1.338688389, -1.332015649, -1.344951753, -1.344769267, -1.345214102,
-1.342514477, -1.343145083, -1.343620358, -1.34275518, -1.340629756,
-1.339067762, -1.338035147, -1.335442485, -1.346461847, -1.34550727,
-1.34516939, -1.346584124), lat = c(51.76635545, 51.76553293,
51.76450781, 51.76428383, 51.75689245, 51.75615401, 51.75742817,
51.75637019, 51.75666667, 51.75740286, 51.7596281, 51.75976378,
51.75721637, 51.75695556, 51.75701561, 51.75871255, 51.75875955,
51.75720018, 51.76339382, 51.75986347, 51.76597134, 51.76737513,
51.76464054, 51.76481595, 51.76542577, 51.76557477, 51.76682149,
51.7644335, 51.76714421, 51.76681267, 51.76597134, 51.76571265,
51.76447255, 51.76339382, 51.76268887, 51.76062289, 51.76030512,
51.76678776, 51.75996884, 51.75968219, 51.75986347, 51.75998767,
51.76749876, 51.76822905, 51.76474771, 51.76863319, 51.76622254,
51.7655237, 51.76482531, 51.76430735, 51.76450781, 51.76421526,
51.76428383, 51.76308822, 51.76434118, 51.76525265, 51.76642077,
51.7672966, 51.76661139, 51.76598088)), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -60L), groups = structure(list(
Time = c(-25, -23, -22, -20, -20, -14, -14, -11, -11, -11,
-10, -10, -10), Code = c(1L, 1L, 1L, 1L, 3L, 1L, 2L, 1L,
2L, 3L, 1L, 2L, 3L), .rows = structure(list(1L, 19:20, 2:4,
22L, 21L, c(7L, 8L, 11L, 12L, 13L, 14L, 15L, 16L, 17L
), c(5L, 6L, 9L, 10L, 18L), 23:30, 32L, 31L, c(33L, 35L,
41L, 42L, 43L, 45L, 47L, 50L, 52L, 53L, 58L, 59L), c(34L,
36L, 37L, 38L, 39L, 40L, 44L, 46L, 49L, 55L, 56L, 60L
), c(48L, 51L, 54L, 57L)), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -13L), .drop = TRUE))
如果我要手动执行此操作,我会使用 dplyr::filter(Time == "x")
,然后像这样使用 leaflet
制作每个绘图
install.packages("leaflet")
library(leaflet)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plots<- leaflet() %>% setView(lng = -1.324640, lat = 51.770462, zoom = 13.25)
plots %>% addTiles() %>%
addCircleMarkers(data = df, label = ~as.character(df$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = df$Code,
title = 'Codes',
opacity = 2)
如果有比循环更好的解决方案,我也很乐意尝试。
希望这是清楚的,并提前致谢
一种方法是将绘图代码放在一个函数中,该函数的唯一参数是一个数据帧。要为 Time
的每个唯一值制作地图,您可以 split
您的数据 Time
并使用绘图函数遍历拆分的数据集,我使用 [=for 循环而不是循环 lapply
。结果,您会得到一个列表,其中包含 Time
:
的每个值的图
library(leaflet)
library(dplyr)
df_split <- df %>%
ungroup() %>%
split(.$Time)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plot_fun <- function(x) {
leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) |>
addTiles() %>%
addCircleMarkers(data = x, label = ~as.character(x$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = x$Code,
title = 'Codes',
opacity = 2)
}
plots <- lapply(df_split, plot_fun)
length(plots)
#> [1] 7
plots[[1]]
EDIT 如果您想保留或使用之前绘图中的数据,我们基本上可以使用相同的代码并进行一个小改动,即遍历索引并组合 (rbind
) 数据集直到绘图函数中的索引值:
library(leaflet)
library(dplyr)
df_split <- df %>%
ungroup() %>%
split(.$Time)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plot_fun <- function(ix) {
x <- do.call(rbind, df_split[seq(ix)])
leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) |>
addTiles() %>%
addCircleMarkers(data = x, label = ~as.character(x$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = x$Code,
title = 'Codes',
opacity = 2)
}
plots <- lapply(seq_along(df_split), plot_fun)
plots[[3]]
plots[[5]]
一种方法是将 Time-wise 传单地图存储在 tibble
:
的列中
## create your base map (only needed once):
base_map <- leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) %>%
addTiles()
all_plots <-
df %>% ## df is your tibble given above
group_by(Time) %>%
## compact the data apart from Time as dataframes per Time-group
## into column "nested_data"
nest(nested_data = c(Site, Code, lon, lat)) %>%
rowwise %>%
mutate(leaflet_map = list(
base_map %>%
addCircleMarkers(data = nested_data, ## the column of dataframes
label = ~as.character(Site),
radius = 5,
color = ~statecol(Code),
stroke = FALSE,
fillOpacity = 5
)
)
) %>%
select(Time, leaflet_map)
生成的 tibble 可以被过滤和迭代(在列 leaflet_plot 上)以自动显示地图。
## for single map at Time == -25
all_plots %>%
filter(Time == -25) %>%
pull(leaflet_map) %>%
print
在此处查找一次性显示多张地图的解决方案:Multiple leaflets in a grid
我是使用循环和简化代码的新手。
我有一个地点数据集,其中包含我想在单独地图上绘制的随附数据。我可以单独绘制地图。
但是我想稍微自动化这个过程,我每天都有新数据到达,不想重复清理数据和重写代码的过程。
所以我认为 for
循环可能就是答案
我需要的是下面数据中每个 Time
的单独图
所以循环会提取每个 Time
值的所有数据,然后绘制它。
dput(df)
structure(list(Site = c("O242", "O51", "O59", "O71", "C110",
"C116", "C120", "C13", "C132", "C134", "C139", "C140", "C29",
"C30", "C33", "C48", "C56", "C9A", "MP25", "MP67", "B30", "MP2",
"B101", "B11", "B112", "B15", "B197", "B2", "B217", "B22", "B30",
"B95", "MP21", "MP25", "MP33", "MP51", "MP56", "MP6", "MP60",
"MP61", "MP67", "MP77", "EX84", "EX92", "SW130", "O31", "O38",
"O38B", "O48", "O58", "O59", "O68", "O71", "O72", "O81", "O94",
"O207", "O209", "O210", "O215"), Time = c(-25, -22, -22, -22,
-14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-14, -23, -23, -20, -20, -11, -11, -11, -11, -11, -11, -11, -11,
-11, -11, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
-10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10,
-10, -10, -10, -10), Code = c(1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L,
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 3L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 3L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L,
1L, 1L, 1L, 2L, 1L, 2L, 1L, 3L, 2L, 1L, 3L, 1L, 1L, 3L, 2L, 2L,
3L, 1L, 1L, 2L), lon = c(-1.341280663, -1.343562025, -1.343620358,
-1.340629756, -1.332551665, -1.329108814, -1.328655294, -1.330835311,
-1.330715028, -1.33052464, -1.328144549, -1.328287425, -1.329353862,
-1.329343236, -1.33041446, -1.325353001, -1.327279282, -1.332909331,
-1.300122834, -1.299148682, -1.310197641, -1.305886812, -1.308725397,
-1.309505208, -1.309235075, -1.308580716, -1.30959055, -1.308685087,
-1.309426224, -1.306562029, -1.310197641, -1.307564253, -1.301598673,
-1.300122834, -1.299510666, -1.299846899, -1.297823339, -1.305388627,
-1.297220016, -1.297398331, -1.299148682, -1.300378324, -1.333554619,
-1.338688389, -1.332015649, -1.344951753, -1.344769267, -1.345214102,
-1.342514477, -1.343145083, -1.343620358, -1.34275518, -1.340629756,
-1.339067762, -1.338035147, -1.335442485, -1.346461847, -1.34550727,
-1.34516939, -1.346584124), lat = c(51.76635545, 51.76553293,
51.76450781, 51.76428383, 51.75689245, 51.75615401, 51.75742817,
51.75637019, 51.75666667, 51.75740286, 51.7596281, 51.75976378,
51.75721637, 51.75695556, 51.75701561, 51.75871255, 51.75875955,
51.75720018, 51.76339382, 51.75986347, 51.76597134, 51.76737513,
51.76464054, 51.76481595, 51.76542577, 51.76557477, 51.76682149,
51.7644335, 51.76714421, 51.76681267, 51.76597134, 51.76571265,
51.76447255, 51.76339382, 51.76268887, 51.76062289, 51.76030512,
51.76678776, 51.75996884, 51.75968219, 51.75986347, 51.75998767,
51.76749876, 51.76822905, 51.76474771, 51.76863319, 51.76622254,
51.7655237, 51.76482531, 51.76430735, 51.76450781, 51.76421526,
51.76428383, 51.76308822, 51.76434118, 51.76525265, 51.76642077,
51.7672966, 51.76661139, 51.76598088)), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -60L), groups = structure(list(
Time = c(-25, -23, -22, -20, -20, -14, -14, -11, -11, -11,
-10, -10, -10), Code = c(1L, 1L, 1L, 1L, 3L, 1L, 2L, 1L,
2L, 3L, 1L, 2L, 3L), .rows = structure(list(1L, 19:20, 2:4,
22L, 21L, c(7L, 8L, 11L, 12L, 13L, 14L, 15L, 16L, 17L
), c(5L, 6L, 9L, 10L, 18L), 23:30, 32L, 31L, c(33L, 35L,
41L, 42L, 43L, 45L, 47L, 50L, 52L, 53L, 58L, 59L), c(34L,
36L, 37L, 38L, 39L, 40L, 44L, 46L, 49L, 55L, 56L, 60L
), c(48L, 51L, 54L, 57L)), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -13L), .drop = TRUE))
如果我要手动执行此操作,我会使用 dplyr::filter(Time == "x")
,然后像这样使用 leaflet
制作每个绘图
install.packages("leaflet")
library(leaflet)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plots<- leaflet() %>% setView(lng = -1.324640, lat = 51.770462, zoom = 13.25)
plots %>% addTiles() %>%
addCircleMarkers(data = df, label = ~as.character(df$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = df$Code,
title = 'Codes',
opacity = 2)
如果有比循环更好的解决方案,我也很乐意尝试。 希望这是清楚的,并提前致谢
一种方法是将绘图代码放在一个函数中,该函数的唯一参数是一个数据帧。要为 Time
的每个唯一值制作地图,您可以 split
您的数据 Time
并使用绘图函数遍历拆分的数据集,我使用 [=for 循环而不是循环 lapply
。结果,您会得到一个列表,其中包含 Time
:
library(leaflet)
library(dplyr)
df_split <- df %>%
ungroup() %>%
split(.$Time)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plot_fun <- function(x) {
leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) |>
addTiles() %>%
addCircleMarkers(data = x, label = ~as.character(x$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = x$Code,
title = 'Codes',
opacity = 2)
}
plots <- lapply(df_split, plot_fun)
length(plots)
#> [1] 7
plots[[1]]
EDIT 如果您想保留或使用之前绘图中的数据,我们基本上可以使用相同的代码并进行一个小改动,即遍历索引并组合 (rbind
) 数据集直到绘图函数中的索引值:
library(leaflet)
library(dplyr)
df_split <- df %>%
ungroup() %>%
split(.$Time)
statecol<- colorFactor(palette = "viridis", df$Code) #create the colour palette
plot_fun <- function(ix) {
x <- do.call(rbind, df_split[seq(ix)])
leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) |>
addTiles() %>%
addCircleMarkers(data = x, label = ~as.character(x$Site), radius = 5, color = ~statecol(Code), stroke = FALSE, fillOpacity = 5) %>%
addLegend('bottomright', pal = statecol, values = x$Code,
title = 'Codes',
opacity = 2)
}
plots <- lapply(seq_along(df_split), plot_fun)
plots[[3]]
plots[[5]]
一种方法是将 Time-wise 传单地图存储在 tibble
:
## create your base map (only needed once):
base_map <- leaflet() %>%
setView(lng = -1.324640, lat = 51.770462, zoom = 13.25) %>%
addTiles()
all_plots <-
df %>% ## df is your tibble given above
group_by(Time) %>%
## compact the data apart from Time as dataframes per Time-group
## into column "nested_data"
nest(nested_data = c(Site, Code, lon, lat)) %>%
rowwise %>%
mutate(leaflet_map = list(
base_map %>%
addCircleMarkers(data = nested_data, ## the column of dataframes
label = ~as.character(Site),
radius = 5,
color = ~statecol(Code),
stroke = FALSE,
fillOpacity = 5
)
)
) %>%
select(Time, leaflet_map)
生成的 tibble 可以被过滤和迭代(在列 leaflet_plot 上)以自动显示地图。
## for single map at Time == -25
all_plots %>%
filter(Time == -25) %>%
pull(leaflet_map) %>%
print
在此处查找一次性显示多张地图的解决方案:Multiple leaflets in a grid