0

This question is for a project and nothing to do with homeworks/acads. I am a working statistician. So my question is, how would you write a R function, given a matrix with 400 rows and two columns where every 20 rows starting from the first, form a first row of coordinates in a grid of points like below where I would like the function to return the four corners of each individual square/rectangle within the grid:

Hence the output would have four columns and each row would indicate a rectangle. I am only looking at adjacent rectangles of the same size as in for example if the numbers below denote the row indices of the example matrix (which has two columns):

Example of row indices:

1  2  3
4  5  6
7  8  9

Would have to be traversed in the following order:

[1,2,4,5],[2,3,5,6],[4,5,7,8],[5,6,8,9] and

return the corresponding 2d points from the example input data set which would have 9 rows and 2 points. But just that, here the grid is specified to be 3 by 3 while in my example the grid is 20 by 20 and my input dataset is 400 rows by 2 columns. If you look at the traversed result there is a pattern wherethe row indices in each 4 point block are incremented by 1. i just want to generalize this to a 400 by 2 or any setting where there is a 2 column matrix of points and there is a mention of the grid dimension.

enter image description here

4

2 回答 2

1

如果我理解正确,这是一个解决方案。老实说,这是一个非常有趣的问题。:D

这个想法是制作一个给定边长的盒子,然后在网格周围移动这个盒子并记录它的顶点。请参阅以下内容:

# Assuming the grid is always a square grid.

grid.size <- 20

# The matrix of row indices.

rindex.grid <- matrix(1:(grid.size * grid.size),
                  nrow=grid.size, ncol=grid.size, byrow=TRUE)

# We can traverse the grid by moving any given square either right or down in any 
# single  move. We choose to go right.

move.square.right <- function (this.square, steps=1) {
  new.square <- this.square + steps
}

# Going right, capture co-ordinates of all squares in this row.

collect.sq.of.edge.length.in.row.number <- function (grid.size, elength,
                                                    rownum=1) {
  first.square.in.row <- (rownum - 1) * grid.size + c(1, elength)
  first.square.in.row <- c(first.square.in.row,
                          first.square.in.row + grid.size * (elength - 1))
  squares.in.row <- t(sapply(X=seq_len(grid.size - (elength - 1)) - 1,
                            FUN=move.square.right,
                            this.square=first.square.in.row))
  squares.in.row
}

# Now we start going down the columns and using the function above to collect
# squares in each row. The we will rbind the list of squares in each row into a
# dataframe. So what we get is a (grid.size - (elength - 1) ^ 2) x 4 matrix where
# each row is the co-ordinates of a square of edge length elength.

collect.sq.of.edge.length.in.grid <- function (grid.size, elength) {
  all.squares=lapply(X=seq_len(grid.size - (elength - 1)),
          FUN=collect.sq.of.edge.length.in.row.number,
          grid.size=grid.size, elength=elength)
  all.squares <- do.call(rbind, all.squares)
  all.squares
}

这似乎表明我们为所有边长获得了正确数量的框:

tmp <- sapply(1:20, collect.sq.of.edge.length.in.grid, grid.size=grid.size)
sapply(tt, nrow)

[1] 400 361 324 289 256 225 196 169 144 121 100  81  64  49  36  25  16   9   4   1

另外,它在您的 3x3 示例中运行良好:

collect.sq.of.edge.length.in.grid(grid.size=3, elength=2)

     [,1] [,2] [,3] [,4]
[1,]    1    2    4    5
[2,]    2    3    5    6
[3,]    4    5    7    8
[4,]    5    6    8    9
于 2013-06-10T19:16:39.690 回答
1

If you want to create a movable 20 x 20 "window" that can scroll down and/or across a 400x400 space, then use:

 mcorners <- function(xidx, yidx) mat[xidx:(xidx+19),
                                       yidx:(yidx+19])

 mcorners(1,1) # should return mat[1:20, mat1:20]

Then supply mcorners() with arguments to fit your somewhat vaguely described needs. The traversal down the first column might involve:

 sapply(1:381, function(ix) yourfunc( mcorners(ix, 1) ) )
于 2013-06-10T18:29:53.843 回答