我已经模拟了来自R中多元正态分布的两组数据,如下所示:
#Package to generate a multivariate normal distribution
library(mvtnorm)
#The number of simulated variables that can be changed
p=5
set.seed(30)
#Generating the eigenvalues from a uniform distribution.
m=p
eigval <- runif(m,0.25,1)
#Generating a positive symmetric matrix (this will be used as the covariance matrix for generation of the data.
#Ravi Varadhan(2008)
shat <- matrix(ncol=m, rnorm(m^2))
decomp <- qr(shat)
Q <- qr.Q(decomp)
R <- qr.R(decomp)
d <- diag(R)
ph <- d/abs(d)
O <- Q%*%diag(ph)
shat <- t(O)%*%diag(eigval)%*%(O)
#Variance-covariance matrix for the data generation.
sig <- shat
#Mean vectors for two groups where the parameters may be changed accordingly.
m1 <- runif(p,0.1,0.2)
m2 <- runif(p,0.4,0.9)
#Euclidean distance between two groups
dist(rbind(m1,m2), method = "euclidean")
#The number of observations from group1
n1 <- 30
#The number of observation from group2
n2 <- 70
#The total number of observations
n <- n1+n2
#Group Identifier where '1' represent group 1 and '2' represent group 2
G1 <- rep(1,n1)
G2 <- rep(2,n2)
G <- c(G1,G2)
#Generate Data from group
library(mvtnorm)
g1 <- rmvnorm(n=n1, mean=m1, sigma=sig)
g2 <- rmvnorm(n=n2, mean=m2, sigma=sig)
g <-rbind(g1,g2)
Data <- data.frame(G, DV1=g[ , 1], DV2=g[ , 2], DV3=g[ ,3], DV4=g[,4], DV5=g[ ,5])
https://stat.ethz.ch/R-manual/R-devel/library/MASS/html/qda.html
然而,在该示例中,据说内置IRIS数据已被分成布置为尺寸50乘4乘3的三维阵列的数据,如S-PLUS所示。 (见 - https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/iris.html)
有人能告诉我如何将数据分成n x m x p?
答案 0 :(得分:0)
不确定您是否需要回答代码或iris3
的问题。我会谈谈后者。
它是一个整洁的array
3维度的事实是方便和演示。这是有效的,因为埃德加安德森收获了每个物种的50个样本。立即文档中没有任何内容表明第一个 setosa 与第一个 virginica 之间存在相关配对,因此数据未配对 。不幸的是,通过将物种安排在立方体中作为平面,它暗示了这种配对关系。
考虑一下:如果埃德加取代了51 setosa 而不是50,但将其他两个物种保持在50,阵列怎么样?其中一架飞机比其他飞机高一点,而不是矩阵。如果他以不同的顺序对50 setosa 进行抽样(因为没有说明订单很重要),该怎么办?数组会有所不同,查看第3个边距(iris3[1,1,]
)的分析会返回不同的结果,但实际数据确实没有变化。
所以,我认为它处于一个完美排列的三维矩阵中的事实是为了处理多维数据,而不是因为数据实际上属于那个方向。
修改强>
鉴于您想知道如何将(任何)数据从2D转换为3D数组,以下是使用iris
的示例。这有几个假设:
所有数据都是相同的class
。例如,在下面的示例中,我删除了$Species
列;因为array
要求内部的所有内容都是同一个类,如果我没有删除它,那么所有的数字都会被转换为字符,可能不是你想要的。
如上所述,增加维度内的配对实际上是相关的。如果数据没有配对,这个过程就可以正常工作,那么考虑到其他数据,不同类别的数据可能有不同的计数,这是完全合乎逻辑的。
与#2相似(并列),所有类别都应具有相同数量的数据。如果您愿意接受NA
行以扩展较短的类别,这可以挥之不去,但这对我来说似乎有点草率。
首先,我们将当前的2D数据分成若干组,方便地(但必然)产生具有相同尺寸(50 x 4)的元素。 -5
删除了第五列$Species
,以便我们使用as.matrix
的下一步不会将numeric
转换为character
。
irislist <- by(iris, iris$Species, `[`, -5)
根据源数据的尺寸预填充3D数组。
mtx <- array(NA, dim = c(dim(irislist[[1]]), length(irislist)))
这可以通过其中一个*apply
函数来完成,但我无法让它一直工作。也许有人可以提出建议。
for (i in seq_along(irislist)) mtx[,,i] <- as.matrix(irislist[[i]])
制作3D矩阵!尽管不是严格要求,但为它添加维名称可能会很好:
dimnames(mtx) <- list(NULL, colnames(irislist[[1]]), names(irislist))
mtx
# , , setosa
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# [1,] 5.1 3.5 1.4 0.2
# [2,] 4.9 3.0 1.4 0.2
# [3,] 4.7 3.2 1.3 0.2
# [4,] 4.6 3.1 1.5 0.2
# [5,] 5.0 3.6 1.4 0.2
# ...snip...
abind
也可以使用abind
完成此操作,无需预先分配mtx
,进行for
循环,或执行任何维度命名:
library(abind)
mtx2 <- do.call("abind", c(irislist, list(along = 3)))
str(mtx)
# num [1:50, 1:4, 1:3] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
# - attr(*, "dimnames")=List of 3
# ..$ : NULL
# ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
# ..$ : chr [1:3] "setosa" "versicolor" "virginica"
这对于您的数据如何处理并不明显。当我运行你的代码时,我最终得到了六列,其中只有一列(Data$G
)似乎是你可以分成另一个维度的东西(也就是说它看起来可能是分类的)。不幸的是:
table(Data$G)
# 1 2
# 30 70
根据我的第三个子弹,这不起作用。