在 R 中创建所有数组索引的数据框

发布于 2024-12-08 13:57:14 字数 785 浏览 2 评论 0原文

使用 R,我尝试构建给定矩阵的行数和列数的数据框。例如,如果

a   <- matrix(c(1:15), nrow=5, ncol=3)

我想要构建一个数据框,给出:

row col
  1   1
  1   2
  1   3
  .   .
  5   1
  5   2
  5   3

我尝试过的:

row <- matrix(row(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
col <- matrix(col(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
out <- cbind(row, col)
colnames(out) <- c("row", "col")

结果:

    row col
[1,]   1   1
[2,]   2   1
[3,]   3   1
[4,]   4   1
[5,]   5   1
[6,]   1   2
[7,]   2   2
[8,]   3   2
[9,]   4   2
[10,]  5   2
[11,]  1   3
[12,]  2   3
[13,]  3   3
[14,]  4   3
[15,]  5   3

这不是我想要的,因为行和列的顺序突然颠倒了,甚至我指定的很难“拜罗=T”。我不知道我是否以及在哪里犯了错误,但非常感谢克服这个问题的建议。提前致谢!

Using R, I'm trying to construct a dataframe of the row and col numbers of a given matrix. E.g., if

a   <- matrix(c(1:15), nrow=5, ncol=3)

then I'm looking to construct a dataframe that gives:

row col
  1   1
  1   2
  1   3
  .   .
  5   1
  5   2
  5   3

What I've tried:

row <- matrix(row(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
col <- matrix(col(a), ncol=1, nrow=dim(a)[1]*dim(a)[2], byrow=T)
out <- cbind(row, col)
colnames(out) <- c("row", "col")

results in:

    row col
[1,]   1   1
[2,]   2   1
[3,]   3   1
[4,]   4   1
[5,]   5   1
[6,]   1   2
[7,]   2   2
[8,]   3   2
[9,]   4   2
[10,]  5   2
[11,]  1   3
[12,]  2   3
[13,]  3   3
[14,]  4   3
[15,]  5   3

Which isn't what I'm looking for, as the sequence of rows and cols in suddenly reversed, even tough I specified "byrow=T". I don't see if and where I'm making a mistake but would hugely appreciate suggestions to overcome this problem. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

三人与歌 2024-12-15 13:57:14

我将在向量 1:ncol 和 1:nrow 上使用 Expand.grid,然后用 [,2:1] 翻转列以按照您想要的顺序获取它们:

> expand.grid(seq(ncol(a)),seq(nrow(a)))[,2:1]
   Var2 Var1
1     1    1
2     1    2
3     1    3
4     2    1
5     2    2
6     2    3
7     3    1
8     3    2
9     3    3
10    4    1
11    4    2
12    4    3
13    5    1
14    5    2
15    5    3

I'd use expand.grid on the vectors 1:ncol and 1:nrow, then flip the columns with [,2:1] to get them in the order you want:

> expand.grid(seq(ncol(a)),seq(nrow(a)))[,2:1]
   Var2 Var1
1     1    1
2     1    2
3     1    3
4     2    1
5     2    2
6     2    3
7     3    1
8     3    2
9     3    3
10    4    1
11    4    2
12    4    3
13    5    1
14    5    2
15    5    3
青巷忧颜 2024-12-15 13:57:14

使用 rowcol,但更直接地操作它们的输出顺序,因为它们返回输入数组的相应索引。使用 t 获得您最终想要的非默认顺序:

data.frame(row = as.vector(t(row(a))), col = as.vector(t(col(a))))
    row col
 1    1   1
 2    1   2
 3    1   3
 4    2   1
 5    2   2
 6    2   3
 7    3   1
 8    3   2
 9    3   3
 10   4   1
 11   4   2
 12   4   3
 13   5   1
 14   5   2
 15   5   3

或者,作为矩阵而不是 data.frame:

cbind(as.vector(t(row(a))), as.vector(t(col(a))))
  [,1] [,2]
 [1,]    1    1
 [2,]    1    2
 [3,]    1    3
 [4,]    2    1
 [5,]    2    2
 [6,]    2    3
 [7,]    3    1
 [8,]    3    2
 [9,]    3    3
 [10,]   4    1
 [11,]   4    2
 [12,]   4    3
 [13,]   5    1
 [14,]   5    2
 [15,]   5    3

Use row and col, but more directly manipulate their output ordering since they return corresponding indices in place for the input array. Use t to get the non-default order you want in the end:

data.frame(row = as.vector(t(row(a))), col = as.vector(t(col(a))))
    row col
 1    1   1
 2    1   2
 3    1   3
 4    2   1
 5    2   2
 6    2   3
 7    3   1
 8    3   2
 9    3   3
 10   4   1
 11   4   2
 12   4   3
 13   5   1
 14   5   2
 15   5   3

Or, as a matrix not a data.frame:

cbind(as.vector(t(row(a))), as.vector(t(col(a))))
  [,1] [,2]
 [1,]    1    1
 [2,]    1    2
 [3,]    1    3
 [4,]    2    1
 [5,]    2    2
 [6,]    2    3
 [7,]    3    1
 [8,]    3    2
 [9,]    3    3
 [10,]   4    1
 [11,]   4    2
 [12,]   4    3
 [13,]   5    1
 [14,]   5    2
 [15,]   5    3
瞎闹 2024-12-15 13:57:14

您可能想看看?expand.grid,它几乎完全符合您想要实现的目标。

You may want to have a look at ?expand.grid, which does just about exactly what you want to achieve.

云归处 2024-12-15 13:57:14

由于给猫剥皮的方法有很多种,我将根据 rep 提供另一种变体:

data.frame(row=rep(seq(nrow(a)), each=ncol(a)), col=rep(seq(ncol(a)), nrow(a)))

...但要宣布“获胜者”,我认为您需要计算解决方案的时间:

# Make up a huge matrix...
a <- matrix(runif(1e7), 1e4)

system.time( a1<-data.frame(row = as.vector(t(row(a))),
                            col = as.vector(t(col(a)))) ) # 0.68 secs

system.time( a2<-expand.grid(col = seq(ncol(a)),
                             row = seq(nrow(a)))[,2:1] ) # 0.49 secs

system.time( a3<-data.frame(row=rep(seq(nrow(a)), each=ncol(a)),
                            col=rep(seq(ncol(a)), nrow(a))) ) # 0.59 secs

identical(a1, a2) && identical(a1, a3) # TRUE

...看来@Spacedman 拥有最快的解决方案!

Since there are many ways to skin a cat, I'll chip in with yet another variant based on rep:

data.frame(row=rep(seq(nrow(a)), each=ncol(a)), col=rep(seq(ncol(a)), nrow(a)))

...but to announce a "winner", I think you need to time the solutions:

# Make up a huge matrix...
a <- matrix(runif(1e7), 1e4)

system.time( a1<-data.frame(row = as.vector(t(row(a))),
                            col = as.vector(t(col(a)))) ) # 0.68 secs

system.time( a2<-expand.grid(col = seq(ncol(a)),
                             row = seq(nrow(a)))[,2:1] ) # 0.49 secs

system.time( a3<-data.frame(row=rep(seq(nrow(a)), each=ncol(a)),
                            col=rep(seq(ncol(a)), nrow(a))) ) # 0.59 secs

identical(a1, a2) && identical(a1, a3) # TRUE

...so it seems @Spacedman has the speediest solution!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文