将数据帧重塑为多维数组

时间:2015-07-22 09:38:41

标签: r multidimensional-array

我的数据框有一个xyz和另一个变量A。

data.frame(xx,yy,zz,Amp)
           xx       yy           zz   Amp
1    63021.71 403205.0  1.181028516  1170
2    63021.71 403105.0  0.977028516  1381
3    63021.71 403105.0  0.861028516   807
4    63021.71 403105.0  0.784028516   668
5    53021.71 403105.0  0.620028516 19919
6    53021.71 403305.0  0.455028516 32500
7    53021.71 403105.0  0.446028516 32500
8    43021.71 403105.0  0.436028516 32500
9    43021.71 404105.0  0.426028516 32500
10   43021.71 403105.0  0.281028516 17464

首先,我想为xyz创建常规网格。

接下来我想用Amp值填充此网格。 我想通过使用数组创建来做到这一点。 任何帮助将不胜感激。

我希望最终结果如下:

dim(Amp)
10 10 10

1 个答案:

答案 0 :(得分:0)

您的MWE中没有足够的数据来创建没有插值的10x10x10数组。当前,您有3个唯一的xx值,4个唯一的yy值和10个唯一的zz值。因此,您可以创建3x4x10数组,但Amp中的值不足以分配给3x4x10 3D常规网格中的每个点。您只有10 Amp值,描述3D空间中的10个唯一点。一个3x4x10的常规栅格阵列将具有120 Amp值,栅格中的每个点都一个。此外,常规网格中的值在每个维度上的间距均等,而yy和zz值的间距也不均。

检查每个尺寸的间距:

> diff(sort(unique(xx)))
[1] 10000 10000

> diff(sort(unique(yy)))
[1] 100 100 800

> diff(sort(unique(zz)))
[1] 0.145 0.010 0.010 0.009 0.165 0.164 0.077 0.116 0.204

当前的MWE在3D模式中如下所示:

library(rgl)
plot3d(xx,yy,zz, col="red")

3D plot of OP example data

要形成10x10x10的常规网格,您需要将数据集转换为具有1000个坐标点和Amp值的数据集。鉴于您的MWE,我不确定您要如何执行此操作,但是鉴于当前数据,这是一个示例:

# MWE data
xx = c(63021.71,63021.71,63021.71,63021.71,53021.71,53021.71,53021.71,43021.71,43021.71,43021.71)
yy = c(403205,403105,403105,403105,403105,403305,403105,403105,404105,403105)
zz = c(1.181028516,0.977028516,0.861028516,0.784028516,0.620028516,0.455028516,0.446028516,0.436028516,0.426028516,0.281028516)
Amp = c(1170,1381,807,668,19919,32500,32500,32500,32500,17464)

# create equally-spaced vectors of 10 values in each dimension
xx <- seq(min(xx), max(xx), length.out = 10)
yy <- seq(min(yy), max(yy), length.out = 10)
zz <- seq(min(zz), max(zz), length.out = 10)

# fake up some Amp data points
set.seed(123)
Amp <- runif(1000, min = min(Amp), max=max(Amp))

# directly create a 10x10x10 regular grid of Amp values as an array
dfa <- array(data = Amp, 
             dim = c(10,10,10), 
             dimnames = list(xx,yy,zz)
)
> dim(dfa)
[1] 10 10 10

# Alternatively, make a data.frame first
df <- data.frame(expand.grid(xx,yy,zz))
names(df) <- c("xx","yy","zz")
df$Amp <- Amp  

dfa <- array(data = df$Amp, 
             dim=c(length(unique(df$xx)), 
                   length(unique(df$yy)), 
                   length(unique(df$zz))), 
             dimnames=list(unique(df$xx), unique(df$yy), unique(df$zz))
)

# you'll want to verify that the Amp values were assigned to the correct xyz coordinates. 
# Here's a little function to help:
get_arr_loc = function(x, y, z) {
  x + (y-1)*10 + (z-1)*100
}

# and some arbitrary coordinates checked. This could be done in a more systematic way...    
> df[get_arr_loc(1,1,1), "Amp"] == dfa[1,1,1]
[1] TRUE
> df[get_arr_loc(10,2,1), "Amp"] == dfa[10,2,1]
[1] TRUE
> df[get_arr_loc(3,6,9), "Amp"] == dfa[3,6,9]
[1] TRUE
> df[get_arr_loc(10,10,10), "Amp"] == dfa[10,10,10]
[1] TRUE
相关问题