我有一个包含许多(100+)对坐标的数据框
[lat1] [long2] [lat3] [long4] [..] [..]
30.12 70.25 32.21 70.25 .. ..
31.21 71.32 32.32 75.2 .. ..
32.32 70.25 31.23 75.0 .. ..
此函数在数据框的前两列中绘制一条连接坐标的线
lines(mapproject(x=data$long2, y=data$lat1), col=3, pch=20, cex=.1)
我需要在每对纬度/经度坐标上执行此功能,以便为每条纬度绘制一条新线/未连接线
看这个例子 Operate on every two columns in a matrix我认为我需要创建一个列表,如何为每个列对创建一个列表?
然后,我可以按https://nicercode.github.io/guides/repeating-things/所述使用lapply-如何将我的lines()调用包装在函数中?
完整脚本:
library(maps)
library(mapproj)
data <- read.csv("data.csv")
map('world', proj='orth', fill=TRUE, col="#f2f2f2", border=0, orient=c(90, 0, 0))
lines(mapproject(x=data$long, y=data$lat), col=3, pch=20, cex=.1)
更新的问题
在注释的帮助下,我尝试了一种每两列执行一次sapply的方法,该方法似乎可以按需工作。这是有待改进的地方
df <- data.frame(X1 = c(0, 10, 20),
Y2 = c(80, 85, 90),
X3 = c(3, 10, 15),
Y4 = c(93, 100, 105),
X5 = c(16, 20, 35),
Y6 = c(100, 105, 130))
map('world', proj='orth', fill=TRUE, col="#f2f2f2", border=0, orient=c(90, 0, 0))
sapply(seq(1,5,by=2),function(i) lines(mapproject(x = (df[,i]), y = (df[,(i+1)])), col = 3))
答案 0 :(得分:0)
回复最新问题
此原始答案的更新不依赖于列名的任何内容,但确实依赖于cascadeValidate: false
对中排序的列。由于deepValidate: true
表示期望相反的坐标对,因此我在函数调用中对其进行了切换。
我也不假定列数。
save()
回复原始问题
我认为这可以满足您的要求
(latitude, longitude)
首先,从数据框列名称中获取唯一的整数集。然后,对于每个整数,应用一个函数,该函数选择与该整数匹配的2列并调用?mapproject
。
函数library(dplyr)
library(stringr)
library(maps)
library(mapproj)
lat_lons <- data.frame(lat1 = c(30, 31, 32),
lon1 = c(70, 71, 70),
lat2 = c(32, 32, 31),
lon2 = c(70, 75, 75),
lat3 = c(33, 33, 33),
lon3 = c(72, 73, 74))
ints <- seq(1, ncol(lat_lons) - 1)
map_lines <- function(int) {
lines(mapproject(x = df[, int + 1], y = df[, int]), col = 3, pch = 20, cex = .1)
}
map('world', proj = 'orth', fill = TRUE, col = "#f2f2f2", border = 0, orient = c(90, 0, 0))
sapply(ints, map_lines)
不返回任何内容,但会作为副作用将线添加到活动绘图中。这不是一种理想的做事方式(我宁愿使用library(dplyr)
library(stringr)
library(maps)
library(mapproj)
lat_lons <- data.frame(lat1 = c(30, 31, 32),
lon1 = c(70, 71, 70),
lat2 = c(32, 32, 31),
lon2 = c(70, 75, 75),
lat3 = c(33, 33, 33),
lon3 = c(72, 73, 74))
ints <- names(lat_lons) %>% str_extract("[0-9]") %>% unique()
map_lines <- function(int) {
df <- select(lat_lons, matches(int))
lines(mapproject(x = df[, 2], y = df[, 1]), col = 3, pch = 20, cex = .1)
}
map('world', proj = 'orth', fill = TRUE, col = "#f2f2f2", border = 0, orient = c(90, 0, 0))
sapply(ints, map_lines)
并在绘制情节之前将其组装在列表中),但它确实可行。
答案 1 :(得分:0)
您的编辑对我有用,但我可能会这样做,因为它的泛化效果更好。
library(maps)
library(mapproj)
df <- data.frame(X1 = c(0, 10, 20),
Y2 = c(80, 85, 90),
X3 = c(3, 10, 15),
Y4 = c(93, 100, 105),
X5 = c(16, 20, 35),
Y6 = c(100, 105, 130))
draw_lines <- function(df){
#Make sure we get the order right for iterating over length
x <- sort(grep("X", names(df), value = TRUE), decreasing = FALSE)
y <- sort(grep("Y", names(df), value = TRUE), decreasing = FALSE)
#Check for vector lengths to be the same
stopifnot(length(x) == length(y))
#I dont want to print anything to console
invisible(lapply(1 : length(x), function(j){
lines(mapproject(x = df[, x[j]], y = df[, y[j]]), col = 3, pch = 20, cex = .1)
})
)
}
然后:
map('world', proj='orth', fill=TRUE, col="#f2f2f2", border=0, orient=c(90, 0, 0))
draw_lines(df = df)
希望这会有所帮助