我希望能够构建do.call子集化的公式,而不必识别输入数组中每个维度的实际范围.我遇到的问题是我无法弄清楚如何模仿直接函数x[,,1:n,],其他维度中没有条目意味着"抓住所有元素".
这是一些示例代码,它失败了.据我所知,[或者do.call用索引替换我的NULL列表值1.
x<-array(1:6,c(2,3))
dimlist<-vector('list', length(dim(x)))
shortdim<-2
dimlist[[shortdim]] <- 1: (dim(x)[shortdim] -1)
flipped <- do.call(`[`,c(list(x),dimlist))
Run Code Online (Sandbox Code Playgroud)
我想我可以通过-2*max(dim(x))为每个元素分配值来解决问题dimlist,但是很糟糕.
(FWIW,我有替代功能,可以通过melt/recast或者可怕的"构建一个字符串然后eval(parse(mystring)),但我想要做得更好"来完成所需的工作.")
编辑:作为一个旁边,我运行了这个代码的版本(相当于DWin的TRUE设置)对使用的函数melt & acast; 后者慢几倍,没有真正意外.
Hon*_*Ooi 14
经过一番探讨后,alist似乎可以做到这一点:
x <- matrix(1:6, nrow=3)
x
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
# 1st row
do.call(`[`, alist(x, 1, ))
[1] 1 4
# 2nd column
do.call(`[`, alist(x, , 2))
[1] 4 5 6
Run Code Online (Sandbox Code Playgroud)
来自?alist:
'alist'处理它的参数,好像它们描述了函数参数.因此不评估值,并且允许没有值的标记参数,而'list'只是忽略它们.'alist'最常用于'formals'.
alist所需长度的初始值,请参见此处(Hadley,使用bquote)或此处(使用alist).
m <- array(1:24, c(2,3,4))
ndims <- 3
a <- rep(alist(,)[1], ndims)
for(i in seq_len(ndims))
{
slice <- a
slice[[i]] <- 1
print(do.call(`[`, c(list(m), slice)))
}
[,1] [,2] [,3] [,4]
[1,] 1 7 13 19
[2,] 3 9 15 21
[3,] 5 11 17 23
[,1] [,2] [,3] [,4]
[1,] 1 7 13 19
[2,] 2 8 14 20
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Run Code Online (Sandbox Code Playgroud)
42-*_*42- 11
我总是TRUE在这个例子中用作占位符:
> x
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> do.call("[", list(x, TRUE,1))
[1] 1 2
Run Code Online (Sandbox Code Playgroud)
让我们使用一个更复杂的x例子:x <- array(1:36, c(2,9,2)那么,如果希望在下标列表中替换一个向量,它将恢复所有第一维和第二维以及第三维的第二个"切片":
shortdim <- 3
short.idx <- 2
dlist <- rep(TRUE, length(dim(x)) )
dlist <- as.list(rep(TRUE, length(dim(x)) ))
> dlist
[[1]]
[1] TRUE
[[2]]
[1] TRUE
[[3]]
[1] TRUE
> dlist[shortdim] <- 2
> do.call("[", c(list(x), dlist) )
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 19 21 23 25 27 29 31 33 35
[2,] 20 22 24 26 28 30 32 34 36
Run Code Online (Sandbox Code Playgroud)
有时候有用的另一点是逻辑索引被循环使用,因此您可以使用c(TRUE,FALSE)来挑选其他所有项:
(x<-array(1:36, c(2,9,2)))
, , 1
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 3 5 7 9 11 13 15 17
[2,] 2 4 6 8 10 12 14 16 18
, , 2
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 19 21 23 25 27 29 31 33 35
[2,] 20 22 24 26 28 30 32 34 36
> x[TRUE,c(TRUE,FALSE), TRUE]
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 19 23 27 31 35
[2,] 20 24 28 32 36
Run Code Online (Sandbox Code Playgroud)
并且可以对每个其他项目进行进一步的变化.尝试使用c(FALSE,FALSE,TRUE)来获取以item-3开头的每个第三个项目.
不是一个直接的答案,但我会演示asub作为替代,因为我很确定这是OP最终会追求的.
library(abind)
Run Code Online (Sandbox Code Playgroud)
提取第1行:
asub(x, idx = list(1), dims = 1)
Run Code Online (Sandbox Code Playgroud)
提取第二和第三列:
asub(x, idx = list(2:3), dims = 2)
Run Code Online (Sandbox Code Playgroud)
shortdimOP想要从维度中删除最后一项:
asub(x, idx = list(1:(dim(x)[shortdim]-1)), dims = shortdim)
Run Code Online (Sandbox Code Playgroud)
您也可以使用否定索引,这样也可以使用:
asub(x, idx = list(-dim(x)[shortdim]), dims = shortdim)
Run Code Online (Sandbox Code Playgroud)
最后,我会提到该函数有一个drop选项就像[那样.
| 归档时间: |
|
| 查看次数: |
551 次 |
| 最近记录: |