如何在r中裁剪(切碎);

发布于 2025-01-20 15:15:02 字数 1607 浏览 7 评论 0原文

我想裁剪一个栅格,然后将每个和平与栅格的各个部分保存到一个列表(或其他方式)中。

想法:

  • 保持所有棋子的覆盖面积相等。
  • 用户可以设置要裁剪的范围区域的百分比。即总面积的10%、20%、30%应该是网格的范围。

下面可以看到一段可重现的代码:它是由 Chris罗伯特·希曼斯在此问题。

library(terra)
r <- rast(volcano)
n <- 10

获取感兴趣的起始单元格

rows <- seq(1, nrow(r), by=n)
cols <- seq(1, ncol(r), by=n)    
cells <- cellFromRowColCombine(r, rows, cols)

获取坐标

起始单元格的左上角坐标

xy <- xyFromCell(r, cells)
rs <- res(r)
xy[,1] <- xy[,1] - rs[1]/2
xy[,2] <- xy[,2] + rs[2]/2

添加结束单元格的右下角坐标

xy <- cbind(xy[,1], xy[,1] + n*rs[1], xy[,2] - n*rs[2], xy[,2])

并循环

x <- lapply(1:nrow(xy), function(i) {
         crop(r, xy[i,])
       })

验证

e <- lapply(x, \(i) ext(i) |> as.polygons()) |> vect()
plot(r)
lines(e, col="blue", lwd=2)

在此处输入图像描述

注意裁剪后的栅格的右侧。对这些多边形进行统计似乎很糟糕。

还: 我想:

  • 开头的 n 表示要在小栅格中裁剪的区域的百分比
  • 用户可以输入 10、20 或 30 作为数字,例如,表示百分比决定要裁剪的“窗口”大小的命令
  • 为了在窗口上保留相等的空间,为此,该命令应该在 10 到 20 之间稍微变化,例如,以保持对称性。

I want to crop a raster and then save each peace into a list (or another way) with the pieces of the raster.

The idea:

  • To preserve the covered area as equal for all of the pieces.
  • To be possible for the user to set a percentage of extent area to be cropped. I.e. 10, 20, 30% of the all-area should be the extent of the grid.

A piece of reproducible code can be seen below: It has been developed by Chris and Robert Hijmans at this question here.

library(terra)
r <- rast(volcano)
n <- 10

Get the starting cells of interest

rows <- seq(1, nrow(r), by=n)
cols <- seq(1, ncol(r), by=n)    
cells <- cellFromRowColCombine(r, rows, cols)

Get the coordinates

upper-left coordinates of the starting cells

xy <- xyFromCell(r, cells)
rs <- res(r)
xy[,1] <- xy[,1] - rs[1]/2
xy[,2] <- xy[,2] + rs[2]/2

add the lower-right coordinates of the end cell

xy <- cbind(xy[,1], xy[,1] + n*rs[1], xy[,2] - n*rs[2], xy[,2])

And loop

x <- lapply(1:nrow(xy), function(i) {
         crop(r, xy[i,])
       })

Verify

e <- lapply(x, \(i) ext(i) |> as.polygons()) |> vect()
plot(r)
lines(e, col="blue", lwd=2)

enter image description here

Note the right side of the cropped raster. It seems bad to perform statistics on these polygons.

Also:
I would like to:

  • the n on the beginning meaning a percentage of the area to be cropped in little rasters
  • The user would enter 10, 20, or 30 as a number, for instance, meaning a percentage on the command to decide the size of the "window" to be cropped
  • To preserve an equal space on the window, and to do that the command should vary a little between 10 and 20, for instance, to preserve the symmetry.

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

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

发布评论

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

评论(1

疯狂的代价 2025-01-27 15:15:02

您确实应该尝试专注于手头的问题,并展示您已经尝试过的内容。因为仍然很难准确地知道你想要什么。无论如何,当 n=20% 和 40(列)乘 60(行)的矩阵时,

cols = 40
rows = 60
n = 20 

您可以找到这样的块大小:

h = sqrt(n/100) * rows
w = sqrt(n/100) * cols 

“proof”

p = h * w
100 * p / (cols * rows) 
# 20

当然 hw不是整数

> h
#[1] 26.83282
> w
#[1] 17.88854

,你会得到

c(seq(1, cols, w) |> round(), cols)
#[1]  1 19 37 40
c(seq(1, rows, h) |> round(), rows)
[1]  1 28 55 60

另一种方法。首先计算块的数量。 20%就是五。在大多数情况下,这实际上应该是偶数,除非您采用整行或整列,因此您无法准确得到该数字。

# number of blocks
nb <- 100/n 
# block rows and cols
brow <- round(nb * rows/(rows+cols))
brow
#[1] 3
bcol <- round(nb / brow)
bcol
#[1] 2

现在你也许可以使用:

round(c(seq(1, rows, rows/brow), rows))
#[1]  1 21 41 60
round(c(seq(1, cols, cols/bcol), cols))
#[1]  1 21 40

You should really try to focus on the question at hand, and show what you have tried. Because it remains hard to know what you want exactly. Anyway, with n=20% and a matrix of 40 (columns) by 60 (rows)

cols = 40
rows = 60
n = 20 

You can find block size like this:

h = sqrt(n/100) * rows
w = sqrt(n/100) * cols 

"proof"

p = h * w
100 * p / (cols * rows) 
# 20

Of course h and w are not integers

> h
#[1] 26.83282
> w
#[1] 17.88854

And you would get

c(seq(1, cols, w) |> round(), cols)
#[1]  1 19 37 40
c(seq(1, rows, h) |> round(), rows)
[1]  1 28 55 60

Another approach. First compute the number of blocks. With 20% that is five. In most cases, that should really be an even number, unless you take entire rows, or columns, so you cannot get exactly that.

# number of blocks
nb <- 100/n 
# block rows and cols
brow <- round(nb * rows/(rows+cols))
brow
#[1] 3
bcol <- round(nb / brow)
bcol
#[1] 2

And now you can perhaps use:

round(c(seq(1, rows, rows/brow), rows))
#[1]  1 21 41 60
round(c(seq(1, cols, cols/bcol), cols))
#[1]  1 21 40
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文