【问题标题】:spatial data xyz to matrix空间数据 xyz 到矩阵
【发布时间】:2013-02-18 23:10:33
【问题描述】:

我有一个带有 LON、LAT、VALUE 的大型数据框(100,000 行),我想将其转换为矩阵。 (EPSG 中的坐标:3035)。

我用以下命令尝试了 reshape2 包

acast(df, lon~lat, value.var="value") 

效果很好。

当我将坐标转换为“EPSG:4326”并运行相同的代码时,当我得到错误时。

str(df1)
data.frame':    168643 obs. of  3 variables:
 $ x: num  28 28.1 27.8 28 28.1 ...
 $ y: num  71.1 71 71 71 71 ...
 $ z: num  0.0893 0.093 0.085 0.0886 0.0924 ...
> aa=acast(df1, x~y, value.var="z")
Error in seq_len(n) : argument must be coercible to non-negative integer
In addition: Warning message:
In match(seq_len(n), overall, nomatch = NA) : NAs introduced by coercion

对于像下面给出的一个可重复的示例,代码有效,但为什么它是像我这样的大型数据框,我收到错误。它与坐标变换有什么关系吗?

x=c(-8.084929925, -8.01229693, -7.939629855, -7.866928803, -7.794193877, -7.721425179,    -7.648622813, -7.575786885, -7.502917498, -7.430014757, -7.357078769, -7.284109638, -7.211107472, -7.138072377, -7.065004461, -6.99190383)


y=c(53.07977473, 53.09085897, 53.10189964, 53.11289671, 53.12385014, 53.1347599, 53.14562596, 53.15644829, 53.16722685, 53.17796162, 53.18865255, 53.19929962, 53.2099028, 53.22046205, 53.23097734, 53.24144865)

z=c(0.065, 0.063, 0.062, 0, 0, 0, 0.061, 0.062, 0.064, 0.06, 0.069, 0.074, 0.079, 0.08, 0.092, 0.10)

df=data.frame(x,y,z)
acast(df, x~y, value.var="z")

有什么想法吗?

【问题讨论】:

  • 你能让你的例子可重现吗?
  • 适用于这些数据:df <- data.frame(lon=sample(10:20),lat=sample(10:20),value=10:20)
  • @PaulHiemstra 我添加了一个可重复的小例子。
  • 除了对角线元素之外,acast()-ed-matrix 中没有任何内容。除非 x 和 y 位置具有合理的重复程度,否则不应使用矩阵对象。您的所有值和 y 值都是不同的。您需要回到开头并解释您要如何处理这些数据,而不是请求无法实现任何合理目标的建议。
  • @DWin 谢谢。我的 x 和 Y 位置确实有合理程度的重复。我需要根据建模者的要求将数据转换为矩阵以用于某些建模目的。

标签: r


【解决方案1】:

在得到数据的情况下确定这是有道理的,但对于所提供的示例而言,情况并非如此,请执行以下操作:

 mtx <- matrix(NA, nrow=length(unique(df$x)), ncol=length(unique(df$y)) )
 mtx[cbind(order(df$x), order(df$y))] <- df$z

您将丢失有关 x 和 y 距离的任何信息。如果需要,可以将有序的唯一值添加到矩阵 dimnames 中。

dimnames(mtx) <- list( sort(unique(df$x)), sort(unique(df$y) ) )

目前,它们似乎确实是相当有规律的空间,因此也许并非所有空间都丢失了。您可能会发现,在确定什么是“唯一”值之前,测量误差需要某种舍入操作:

> diff(df$x)
 [1] 0.07263300 0.07266708 0.07270105 0.07273493 0.07276870 0.07280237 0.07283593 0.07286939
 [9] 0.07290274 0.07293599 0.07296913 0.07300217 0.07303509 0.07306792 0.07310063
> diff(df$y)
 [1] 0.01108424 0.01104067 0.01099707 0.01095343 0.01090976 0.01086606 0.01082233 0.01077856
 [9] 0.01073477 0.01069093 0.01064707 0.01060318 0.01055925 0.01051529 0.01047131

看起来间隔距离有系统的增加/蠕变:

> diff(diff(df$x))
 [1] 3.4080e-05 3.3977e-05 3.3874e-05 3.3772e-05 3.3668e-05 3.3562e-05 3.3459e-05 3.3354e-05
 [9] 3.3247e-05 3.3143e-05 3.3035e-05 3.2929e-05 3.2821e-05 3.2715e-05
> diff(diff(df$y))
 [1] -4.357e-05 -4.360e-05 -4.364e-05 -4.367e-05 -4.370e-05 -4.373e-05 -4.377e-05 -4.379e-05
 [9] -4.384e-05 -4.386e-05 -4.389e-05 -4.393e-05 -4.396e-05 -4.398e-05

【讨论】:

    【解决方案2】:

    如果数据集不是太大,并且 LAT 和 LON 变量是整数,您可能需要尝试使用 for 循环加载矩阵。即使有 100k 个元素,也不会超过一分钟。

    n = max(df$LON)
    m = max(df$LAT)
    x = matrix(0, nrow=m, ncol=n)
    for (i in nrows(df)){
        x[df[i,"LAT"], df[i,"LON"]] = df[i,"VALUE"]
    }
    

    【讨论】:

    • 这有几个问题: (1) LAT/LON 不是整数会有问题; (2) 它会比其他可能性慢很多
    • 对于这个例子,我得到“下标越界”错误。
    • 如果您有负数或非整数 LAT 和 LON,您需要将它们映射到索引范围。假设您要将结果存储在 100x100 矩阵中。您需要编写一个函数,将 LAT 从范围(例如 0 到 360)转换为范围 1 到 100。然后您可以使用上面的代码,例如:x[lat2ind(df[i,"LAT"] ), lon2ind(df[i,"LON"])] = df[i,"VALUE"]
    猜你喜欢
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    相关资源
    最近更新 更多