R 中的多维数组是否有 inner_join 等价物?
Is there an inner_join equivalent for multidimensional arrays in R?
对于 3d 数组是否有某种 inner_join 等价物,可以将 2d 结构连接到 3d 结构吗?
让我们看看这是否有意义:
我有一个 3d 整数数组(微生物组计数数据)。
- 维度 1:重复 1:100
- 维度 2:样本
- 维度 3:分类群
我有 2d table 元数据。
- 维度 1:样本
- 维度 2:元数据类型(稀释、取样日期等)
二维元数据table(样本名称)中有一列与数组中第二维的标签相匹配。
我能否以某种方式加入这两者,以便保留数组结构并为每个样本添加元数据?
我是否必须将数组 melt/stack 变成一个超长的 2d table?
感谢您的帮助!
-编辑
假设我使用以下代码生成数组 a 和 "a" table "b":
a <- array(1:10,c(2,4,3))
b <- data.frame("thing" = c("stuff", "foo", "dodad"), "data" = c(10,20,30), "match" = c("first","second","third"))
dimnames(a) <- list(c("A", "B"), c("one", "two", "three", "four"), c("first", "second", "third"))
如您所见,我在 table "b" 中有一列 "match",我想 join/match 将其添加到维度名称 a[[3] ].
所以如果我们查看 "a" 和 "b"
> a
, , first
one two three four
A 1 3 5 7
B 2 4 6 8
, , second
one two three four
A 9 1 3 5
B 10 2 4 6
, , third
one two three four
A 7 9 1 3
B 8 10 2 4
> b
thing data match
1 stuff 10 first
2 foo 20 second
3 dodad 30 third
我想要,例如,数组
, , third
one two three four
A 7 9 1 3
B 8 10 2 4
将元素 "dodad" 和“30”与标签 "thing" 和 "data" 相关联。
对于真实的数据集,我想要 "patient name" 而不是 "thing" 和 "dilution" 而不是 "data" 并使用这些元素作为一种手段从数组中提取切片以进行 运行 统计分析。
你没有显示你想要的输出,所以我猜。
如果您从 a
(dims AxBxC)和 b
(dims DxE)开始,那么您应该得到一个包含 dims AxBxD 的数组。
a[,,b[,"match"]]
# , , first
# one two three four
# A 1 3 5 7
# B 2 4 6 8
# , , second
# one two three four
# A 9 1 3 5
# B 10 2 4 6
# , , third
# one two three four
# A 7 9 1 3
# B 8 10 2 4
就组合输出而言,使用您提供的数据不可能发生:矩阵 a
具有所有数据必须相同 class 的约束,但您的 b
是具有不同 classes 的框架。因此,如果您需要在 a
中保留数字,在 b
中保留字符串或因子,那么您不能只将一个与另一个合并。
您有一些选择:
如果你的第二帧真的可以是矩阵,那我们就可以这样
### a naive conversion, your case may vary with real data
bnum <- sapply(b, as.integer)
dim(bnum) <- c(dim(bnum), 1)
dimnames(bnum) <- list(rownames(b), colnames(b), NULL)
bnum
# , , 1
# thing data match
# 1 3 10 1
# 2 2 20 2
# 3 1 30 3
### the solution
abind::abind(
apply(bnum[,-3,1], 2:1, rep, times = dim(a)[1]),
a[,,bnum[,"match",1]],
along = 2
)
# , , first
# thing data one two three four
# A 3 10 1 3 5 7
# B 3 10 2 4 6 8
# , , second
# thing data one two three four
# A 2 20 9 1 3 5
# B 2 20 10 2 4 6
# , , third
# thing data one two three four
# A 1 30 7 9 1 3
# B 1 30 8 10 2 4
如果您需要保持 b
原样,那么您无法制作 3 维数组。一个选项是以列表列的方式嵌套 a
的每一层。
out <- within(b, { mtx = lapply(match, function(m) a[,,m]) })
out
# thing data match mtx
# 1 stuff 10 first 1, 2, 3, 4, 5, 6, 7, 8
# 2 foo 20 second 9, 10, 1, 2, 3, 4, 5, 6
# 3 dodad 30 third 7, 8, 9, 10, 1, 2, 3, 4
虽然看起来它丢失了 a
的 z 层布局,但这在控制台上的表现很差。还是不错的:
out$mtx[[1]]
# one two three four
# A 1 3 5 7
# B 2 4 6 8
如果您有兴趣,也可以使用 dplyr
和 data.table
来完成。
library(dplyr)
out <- b %>%
mutate(mtx = lapply(match, function(m) a[,,m]))
# option to use purrr::map instead of lapply
library(data.table)
out <- as.data.table(b)[, mtx := lapply(match, function(m) a[,,m]) ]
对于 3d 数组是否有某种 inner_join 等价物,可以将 2d 结构连接到 3d 结构吗?
让我们看看这是否有意义:
我有一个 3d 整数数组(微生物组计数数据)。
- 维度 1:重复 1:100
- 维度 2:样本
- 维度 3:分类群
我有 2d table 元数据。
- 维度 1:样本
- 维度 2:元数据类型(稀释、取样日期等)
二维元数据table(样本名称)中有一列与数组中第二维的标签相匹配。
我能否以某种方式加入这两者,以便保留数组结构并为每个样本添加元数据?
我是否必须将数组 melt/stack 变成一个超长的 2d table?
感谢您的帮助!
-编辑
假设我使用以下代码生成数组 a 和 "a" table "b":
a <- array(1:10,c(2,4,3))
b <- data.frame("thing" = c("stuff", "foo", "dodad"), "data" = c(10,20,30), "match" = c("first","second","third"))
dimnames(a) <- list(c("A", "B"), c("one", "two", "three", "four"), c("first", "second", "third"))
如您所见,我在 table "b" 中有一列 "match",我想 join/match 将其添加到维度名称 a[[3] ].
所以如果我们查看 "a" 和 "b"
> a
, , first
one two three four
A 1 3 5 7
B 2 4 6 8
, , second
one two three four
A 9 1 3 5
B 10 2 4 6
, , third
one two three four
A 7 9 1 3
B 8 10 2 4
> b
thing data match
1 stuff 10 first
2 foo 20 second
3 dodad 30 third
我想要,例如,数组
, , third
one two three four
A 7 9 1 3
B 8 10 2 4
将元素 "dodad" 和“30”与标签 "thing" 和 "data" 相关联。
对于真实的数据集,我想要 "patient name" 而不是 "thing" 和 "dilution" 而不是 "data" 并使用这些元素作为一种手段从数组中提取切片以进行 运行 统计分析。
你没有显示你想要的输出,所以我猜。
如果您从 a
(dims AxBxC)和 b
(dims DxE)开始,那么您应该得到一个包含 dims AxBxD 的数组。
a[,,b[,"match"]]
# , , first
# one two three four
# A 1 3 5 7
# B 2 4 6 8
# , , second
# one two three four
# A 9 1 3 5
# B 10 2 4 6
# , , third
# one two three four
# A 7 9 1 3
# B 8 10 2 4
就组合输出而言,使用您提供的数据不可能发生:矩阵 a
具有所有数据必须相同 class 的约束,但您的 b
是具有不同 classes 的框架。因此,如果您需要在 a
中保留数字,在 b
中保留字符串或因子,那么您不能只将一个与另一个合并。
您有一些选择:
如果你的第二帧真的可以是矩阵,那我们就可以这样
### a naive conversion, your case may vary with real data bnum <- sapply(b, as.integer) dim(bnum) <- c(dim(bnum), 1) dimnames(bnum) <- list(rownames(b), colnames(b), NULL) bnum # , , 1 # thing data match # 1 3 10 1 # 2 2 20 2 # 3 1 30 3 ### the solution abind::abind( apply(bnum[,-3,1], 2:1, rep, times = dim(a)[1]), a[,,bnum[,"match",1]], along = 2 ) # , , first # thing data one two three four # A 3 10 1 3 5 7 # B 3 10 2 4 6 8 # , , second # thing data one two three four # A 2 20 9 1 3 5 # B 2 20 10 2 4 6 # , , third # thing data one two three four # A 1 30 7 9 1 3 # B 1 30 8 10 2 4
如果您需要保持
b
原样,那么您无法制作 3 维数组。一个选项是以列表列的方式嵌套a
的每一层。out <- within(b, { mtx = lapply(match, function(m) a[,,m]) }) out # thing data match mtx # 1 stuff 10 first 1, 2, 3, 4, 5, 6, 7, 8 # 2 foo 20 second 9, 10, 1, 2, 3, 4, 5, 6 # 3 dodad 30 third 7, 8, 9, 10, 1, 2, 3, 4
虽然看起来它丢失了
a
的 z 层布局,但这在控制台上的表现很差。还是不错的:out$mtx[[1]] # one two three four # A 1 3 5 7 # B 2 4 6 8
如果您有兴趣,也可以使用
dplyr
和data.table
来完成。library(dplyr) out <- b %>% mutate(mtx = lapply(match, function(m) a[,,m])) # option to use purrr::map instead of lapply library(data.table) out <- as.data.table(b)[, mtx := lapply(match, function(m) a[,,m]) ]