I'd like to join the list of polygons in a data frame, but it is important to sort a set of coordinates in a clockwise direction. In my example:
library(dplyr)
library(sf)
test.all <- list(structure(list(year = "2010", locality_id = "L2228604",
observation_count = 0, geometry = structure(list(structure(list(
structure(c(-8773389.28986396, -8773390.87960364, -8773395.64446533,
-8773403.57138886, -8773414.6386471, -8773428.81590546,
-8773446.06430505, -8773466.33656922, -8773489.57713309,
-8773515.7222959, -8773544.70039557, -8773576.43200514,
-8773610.83015048, -8773647.80054867, -8773687.2418664,
-8773729.04599778, -8773773.09836058, -8773819.27821034,
-8773867.4589713, -8773917.50858334, -8773969.28986396,
-8774022.66088426, -8774077.47535799, -8774133.58304248,
-8774190.83015048, -8774249.05977164, -8774308.11230261,
-8774367.82588451, -8774428.03684657, -8774488.58015471,
-8774549.28986396, -8774609.9995732, -8774670.54288135,
-8774730.7538434, -8774790.4674253, -8774849.51995627,
-8774907.74957743, -8774964.99668543, -8775021.10436992,
-8775075.91884365, -8775129.28986396, -8775181.07114457,
-8775231.12075661, -8775279.30151757, -8775325.48136733,
-8775369.53373013, -8775411.33786151, -8775450.77917925,
-8775487.74957743, -8775522.14772277, -8775553.87933234,
-8775582.85743201, -8775609.00259482, -8775632.24315869,
-8775652.51542286, -8775669.76382245, -8775683.94108081,
-8775695.00833905, -8775702.93526258, -8775707.70012427,
-8775709.28986396, -8775707.70012427, -8775702.93526258,
-8775695.00833905, -8775683.94108081, -8775669.76382245,
-8775652.51542286, -8775632.24315869, -8775609.00259482,
-8775582.85743201, -8775553.87933234, -8775522.14772277,
-8775487.74957743, -8775450.77917925, -8775411.33786151,
-8775369.53373013, -8775325.48136733, -8775279.30151757,
-8775231.12075661, -8775181.07114457, -8775129.28986396,
-8775075.91884365, -8775021.10436992, -8774964.99668543,
-8774907.74957743, -8774849.51995627, -8774790.4674253,
-8774730.7538434, -8774670.54288135, -8774609.9995732,
-8774549.28986396, -8774488.58015471, -8774428.03684657,
-8774367.82588451, -8774308.11230261, -8774249.05977164,
-8774190.83015048, -8774133.58304248, -8774077.47535799,
-8774022.66088426, -8773969.28986396, -8773917.50858334,
-8773867.4589713, -8773819.27821034, -8773773.09836058,
-8773729.04599778, -8773687.2418664, -8773647.80054867,
-8773610.83015048, -8773576.43200514, -8773544.70039557,
-8773515.7222959, -8773489.57713309, -8773466.33656922,
-8773446.06430505, -8773428.81590546, -8773414.6386471,
-8773403.57138886, -8773395.64446533, -8773390.87960364,
-8773389.28986396, 4574141.40786374, 4574080.6981545,
4574020.15484635, 4573959.94388429, 4573900.23030239,
4573841.17777142, 4573782.94815026, 4573725.70104226,
4573669.59335777, 4573614.77888404, 4573561.40786374,
4573509.62658312, 4573459.57697108, 4573411.39621012,
4573365.21636036, 4573321.16399756, 4573279.35986618,
4573239.91854845, 4573202.94815026, 4573168.55000492,
4573136.81839535, 4573107.84029568, 4573081.69513287,
4573058.454569, 4573038.18230483, 4573020.93390524, 4573006.75664689,
4572995.68938865, 4572987.76246511, 4572982.99760342,
4572981.40786374, 4572982.99760342, 4572987.76246511,
4572995.68938865, 4573006.75664689, 4573020.93390524,
4573038.18230483, 4573058.454569, 4573081.69513287, 4573107.84029568,
4573136.81839535, 4573168.55000492, 4573202.94815026,
4573239.91854845, 4573279.35986618, 4573321.16399756,
4573365.21636036, 4573411.39621012, 4573459.57697108,
4573509.62658312, 4573561.40786374, 4573614.77888404,
4573669.59335777, 4573725.70104226, 4573782.94815026,
4573841.17777142, 4573900.23030239, 4573959.94388429,
4574020.15484635, 4574080.6981545, 4574141.40786374,
4574202.11757298, 4574262.66088113, 4574322.87184318,
4574382.58542509, 4574441.63795606, 4574499.86757721,
4574557.11468521, 4574613.22236971, 4574668.03684343,
4574721.40786374, 4574773.18914435, 4574823.2387564,
4574871.41951736, 4574917.59936711, 4574961.65172991,
4575003.45586129, 4575042.89717903, 4575079.86757721,
4575114.26572255, 4575145.99733213, 4575174.9754318,
4575201.1205946, 4575224.36115847, 4575244.63342264,
4575261.88182223, 4575276.05908059, 4575287.12633883,
4575295.05326236, 4575299.81812405, 4575301.40786374,
4575299.81812405, 4575295.05326236, 4575287.12633883,
4575276.05908059, 4575261.88182223, 4575244.63342264,
4575224.36115847, 4575201.1205946, 4575174.9754318, 4575145.99733213,
4575114.26572255, 4575079.86757721, 4575042.89717903,
4575003.45586129, 4574961.65172991, 4574917.59936711,
4574871.41951736, 4574823.2387564, 4574773.18914435,
4574721.40786374, 4574668.03684343, 4574613.22236971,
4574557.11468521, 4574499.86757721, 4574441.63795606,
4574382.58542509, 4574322.87184318, 4574262.66088113,
4574202.11757298, 4574141.40786374), .Dim = c(121L, 2L
))), class = c("XY", "POLYGON", "sfg"))), class = c("sfc_POLYGON",
"sfc"), precision = 0, bbox = structure(c(xmin = -8775709.28986396,
ymin = 4572981.40786374, xmax = -8773389.28986396, ymax = 4575301.40786374
), class = "bbox"), crs = structure(list(input = "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +R=6371007.181 +units=m +no_defs",
wkt = "PROJCRS[\"unknown\",\n BASEGEOGCRS[\"unknown\",\n DATUM[\"unknown\",\n ELLIPSOID[\"unknown\",6371007.181,0,\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8901]]],\n CONVERSION[\"unknown\",\n METHOD[\"Sinusoidal\"],\n PARAMETER[\"Longitude of natural origin\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"False easting\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"(E)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]],\n AXIS[\"(N)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(year = NA_integer_,
locality_id = NA_integer_, observation_count = NA_integer_), class = "factor", .Label = c("constant",
"aggregate", "identity")), row.names = c(NA, -1L), class = c("sf",
"tbl_df", "tbl", "data.frame")), structure(list(year = "2011",
locality_id = "L1472874", observation_count = 0, geometry = structure(list(
structure(list(structure(c(-7214135.48475349, -7214137.07449317,
-7214141.83935486, -7214149.7662784, -7214160.83353664,
-7214175.01079499, -7214192.25919458, -7214212.53145875,
-7214235.77202262, -7214261.91718543, -7214290.8952851,
-7214322.62689467, -7214357.02504001, -7214393.9954382,
-7214433.43675593, -7214475.24088731, -7214519.29325011,
-7214565.47309987, -7214613.65386083, -7214663.70347287,
-7214715.48475349, -7214768.85577379, -7214823.67024752,
-7214879.77793201, -7214937.02504001, -7214995.25466117,
-7215054.30719214, -7215114.02077404, -7215174.2317361,
-7215234.77504424, -7215295.48475349, -7215356.19446273,
-7215416.73777088, -7215476.94873293, -7215536.66231484,
-7215595.71484581, -7215653.94446696, -7215711.19157496,
-7215767.29925945, -7215822.11373318, -7215875.48475349,
-7215927.2660341, -7215977.31564615, -7216025.4964071,
-7216071.67625686, -7216115.72861966, -7216157.53275104,
-7216196.97406878, -7216233.94446696, -7216268.3426123,
-7216300.07422188, -7216329.05232154, -7216355.19748435,
-7216378.43804822, -7216398.71031239, -7216415.95871198,
-7216430.13597034, -7216441.20322858, -7216449.13015211,
-7216453.8950138, -7216455.48475349, -7216453.8950138,
-7216449.13015211, -7216441.20322858, -7216430.13597034,
-7216415.95871198, -7216398.71031239, -7216378.43804822,
-7216355.19748435, -7216329.05232154, -7216300.07422188,
-7216268.3426123, -7216233.94446696, -7216196.97406878,
-7216157.53275104, -7216115.72861966, -7216071.67625686,
-7216025.4964071, -7215977.31564615, -7215927.2660341,
-7215875.48475349, -7215822.11373318, -7215767.29925945,
-7215711.19157496, -7215653.94446696, -7215595.71484581,
-7215536.66231484, -7215476.94873293, -7215416.73777088,
-7215356.19446273, -7215295.48475349, -7215234.77504424,
-7215174.2317361, -7215114.02077404, -7215054.30719214,
-7214995.25466117, -7214937.02504001, -7214879.77793201,
-7214823.67024752, -7214768.85577379, -7214715.48475349,
-7214663.70347287, -7214613.65386083, -7214565.47309987,
-7214519.29325011, -7214475.24088731, -7214433.43675593,
-7214393.9954382, -7214357.02504001, -7214322.62689467,
-7214290.8952851, -7214261.91718543, -7214235.77202262,
-7214212.53145875, -7214192.25919458, -7214175.01079499,
-7214160.83353664, -7214149.7662784, -7214141.83935486,
-7214137.07449317, -7214135.48475349, 4014314.81839922,
4014254.10868998, 4014193.56538183, 4014133.35441977,
4014073.64083787, 4014014.5883069, 4013956.35868575,
4013899.11157775, 4013843.00389325, 4013788.18941952,
4013734.81839922, 4013683.0371186, 4013632.98750656,
4013584.8067456, 4013538.62689584, 4013494.57453304,
4013452.77040167, 4013413.32908393, 4013376.35868575,
4013341.9605404, 4013310.22893083, 4013281.25083116,
4013255.10566836, 4013231.86510448, 4013211.59284032,
4013194.34444073, 4013180.16718237, 4013169.09992413,
4013161.17300059, 4013156.40813891, 4013154.81839922,
4013156.40813891, 4013161.17300059, 4013169.09992413,
4013180.16718237, 4013194.34444073, 4013211.59284032,
4013231.86510448, 4013255.10566836, 4013281.25083116,
4013310.22893083, 4013341.9605404, 4013376.35868575,
4013413.32908393, 4013452.77040167, 4013494.57453304,
4013538.62689584, 4013584.8067456, 4013632.98750656,
4013683.0371186, 4013734.81839922, 4013788.18941952,
4013843.00389325, 4013899.11157775, 4013956.35868575,
4014014.5883069, 4014073.64083787, 4014133.35441977,
4014193.56538183, 4014254.10868998, 4014314.81839922,
4014375.52810846, 4014436.07141661, 4014496.28237867,
4014555.99596057, 4014615.04849154, 4014673.2781127,
4014730.52522069, 4014786.63290519, 4014841.44737892,
4014894.81839922, 4014946.59967984, 4014996.64929188,
4015044.83005284, 4015091.0099026, 4015135.0622654, 4015176.86639678,
4015216.30771451, 4015253.2781127, 4015287.67625804,
4015319.40786761, 4015348.38596728, 4015374.53113009,
4015397.77169396, 4015418.04395812, 4015435.29235772,
4015449.46961607, 4015460.53687431, 4015468.46379785,
4015473.22865954, 4015474.81839922, 4015473.22865954,
4015468.46379785, 4015460.53687431, 4015449.46961607,
4015435.29235772, 4015418.04395812, 4015397.77169396,
4015374.53113009, 4015348.38596728, 4015319.40786761,
4015287.67625804, 4015253.2781127, 4015216.30771451,
4015176.86639678, 4015135.0622654, 4015091.0099026, 4015044.83005284,
4014996.64929188, 4014946.59967984, 4014894.81839922,
4014841.44737892, 4014786.63290519, 4014730.52522069,
4014673.2781127, 4014615.04849154, 4014555.99596057,
4014496.28237867, 4014436.07141661, 4014375.52810846,
4014314.81839922), .Dim = c(121L, 2L))), class = c("XY",
"POLYGON", "sfg"))), class = c("sfc_POLYGON", "sfc"), precision = 0, bbox = structure(c(xmin = -7216455.48475349,
ymin = 4013154.81839922, xmax = -7214135.48475349, ymax = 4015474.81839922
), class = "bbox"), crs = structure(list(input = "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +R=6371007.181 +units=m +no_defs",
wkt = "PROJCRS[\"unknown\",\n BASEGEOGCRS[\"unknown\",\n DATUM[\"unknown\",\n ELLIPSOID[\"unknown\",6371007.181,0,\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8901]]],\n CONVERSION[\"unknown\",\n METHOD[\"Sinusoidal\"],\n PARAMETER[\"Longitude of natural origin\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"False easting\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"(E)\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]],\n AXIS[\"(N)\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(year = NA_integer_,
locality_id = NA_integer_, observation_count = NA_integer_), class = "factor", .Label = c("constant",
"aggregate", "identity")), row.names = c(NA, -1L), class = c("sf",
"tbl_df", "tbl", "data.frame")))
test.all = test.all %>%
dplyr::bind_rows() %>% #bind the list into a data.frame
sf::st_cast(to = "POINT") %>% #convert polygon to a list of points
dplyr::mutate(
X = sf::st_coordinates(geometry)[,1], #retrieve X coord
Y = sf::st_coordinates(geometry)[,2] #retrieve Y coord
) %>%
sf::st_drop_geometry() #drop the geometry column
But I'd like too thetest.all
in coordinates in a clockwise direction. Please, any help with it?
This should be possible by converting to polar coordinates, centered around each group's center (in this case I picked the median x/y).
I use geom_path
here since it plots in order of appearance (vs. geom_line, in order of the x variable).
library(tidyverse)
my_data <- tibble(group = sample(letters[1:3], 100, TRUE),
x = rnorm(100) + 2 * as.numeric(factor(group)),
y = rnorm(100))
my_data |>
mutate(across(x:y, median, .names = "{.col}_med"), .by = group) |>
mutate(theta = atan2(y - y_med, x - x_med)) |>
arrange(theta) |>
ggplot(aes(x, y, group = group, color = group)) +
geom_point() +
geom_path()