【问题标题】:How to find decimal places lower than 2 and fill them with zeros in R如何找到小于2的小数位并在R中用零填充
【发布时间】:2016-01-11 14:41:30
【问题描述】:

我想基于一个公共列合并两个数据集。数据集 A 是一个 geoTIFF 图像,代表一个区域的 RGB 值。数据集 B 是具有相同区域 xyz 值的点云。

我想将图像中的 RGB 信息合并到 3d 数据中。我想使用两个数据集的 x y 坐标(它们在同一个坐标系中)。 我写了一个脚本,灵感来自 stackoverflow 中的代码 sn-ps,但我需要实现我的整个代码(来源是 123)。

问题是两个文件中的 x y 坐标具有不同的精度(十进制数)。数据集 A 有 0 到 2 个数字;数据集 B 有更多。我将数据集 B 的位数四舍五入为 2。现在,当数据集 A 的位数小于 2 时,我想用零填充,这样最终的合并有望成功。

考虑到我的数据集有 >280000 行,是否可以使用简单的 if 语句?还是我应该去索引?无论如何,我在使用 R 方面相当新,所以我希望可能的海报能帮助我提供代码示例。以下是我的代码:

require(raster)
require(rgl)

setwd("C:/my/folder")

# Read tiff file
img <- stack("image.tif")

vals <- extract(img, 1:ncell(img))
coord <- xyFromCell(img, 1:ncell(img))
combine <- cbind(coord, vals)
remove(vals)
remove(coord)

# read POINTCLOUD and assign names
lidar <- read.table("lidardata.txt")
names(lidar) <- c("x","y","z")

decimalplaces <- function(x) {
  if ((x %% 1) != 0) {
    nchar(strsplit(sub('0+$', '', as.character(x)), ".", fixed=TRUE)[[1]][[2]])
  } else {
    return(0)
  }
}


# HERE I SHOULD PAD THE LIDAR VARIABLE WITH ZEROS IN DECIMAL POSITIONS WHEN THE DIGITS ARE LESS THAN 2!!!
lidar$xy <- do.call(paste0,lidar[,1:2])

combine$x <- round(combine$x, digits = 2)
combine$y <- round(combine$y, digits = 2)
combine$xy <- do.call(paste0,combine[1:2])

finaldata <- merge(combine,lidar,by = 'xy', all = FALSE)

编辑 1

正如@Heroka 所建议的,这也是激光雷达(数据集 A)的外观示例,以及用零填充后的外观。

激光雷达(原创)

x     y     z
12    9     87
11    23.4  100

激光雷达(已更改,并添加了“xy”列以进行连接)

x     y     z     xy
12.00 9.00  87    12.009.00
11.00 23.40 100   11.0023.40

编辑 2

我设法用counting &lt;- sapply(lidar$x, decimalplaces) 检索了我的“激光雷达”变量(数据集 B)的所有 x 和 y 中的位数 在上面的示例中(LIDAR 原始),这将为第一 (x) 列提供 [0 0],为第二 (y) 列提供 [0 1]。我应该能够在我的 x y 数据集中找到值为 0 或 1 作为数字(而不是 2)的每一行,并像上面的 LIDAR-altered 中一样用 0 填充。

【问题讨论】:

  • 'sprintf("%02f",....) 会有帮助吗?喜欢sprintf("%.02f",0.1)
  • 我不知道,我认为这是打印的问题,或者我没有理解您的建议。无论如何,我现在正在看这个(stackoverflow.com/questions/4317452/…),这似乎表明了一种方法。谢谢
  • 我将您的问题理解为“我需要一种方法来确保两位数,从而用零填充”,这就是 sprintf 可以做的(您可以将输出保存到变量中)。您能否用激光雷达和组合的某些部分扩展您的问题,以及您的预期结果是什么?
  • 我们这里似乎有一个XY problem

标签: r join raster geotiff lidar


【解决方案1】:

我不明白你为什么需要用零填充。如果坐标属于numeric 类,并且两者都使用round 进行了四舍五入(这应该避免浮点精度问题),那么您应该能够仅通过它们进行合并。像这样的:

lidar$x <- round(lidar$x, 2)
lidar$y <- round(lidar$y, 2)
combine$x <- round(combine$x, digits = 2)
combine$y <- round(combine$y, digits = 2)

finaldata <- merge(combine, lidar, by = c("x", "y") , all = FALSE)

【讨论】:

  • 谢谢。不,只有一个使用round(图像或数据集A)四舍五入,因为它有5位或更多位,而另一个有0到2位。当然,数字越少,合并的精确度就越低(而且我会丢失更多的数据,因为会有很多重复的坐标)。
  • 好吧,那么您需要一种完全不同的方法(例如插值)。将 x 和 y 坐标粘贴在一起绝对不是可行的方法,也不是用零填充(这根本没有区别)。
  • 为什么不呢?据我所知,如果我只是有相同的 xy (转换为字符,这就是为什么我需要相同的位数)它应该使用简单的连接。我在没有填充的情况下尝试了它,我的最终数据中有 4035 行。我认为我丢失的许多行是由于连接没有考虑数据集 A 中的 xy 为 0 和 1 位,数据集 B 为 2 位。
  • 我回答的基本信息是 (i) 你绝对不应该对数值使用文本处理函数(我们有 roundfloor 等)和 (ii) 你可以合并一列以上。
  • 谢谢。确实,我正在努力实现我想要的方式肯定不是最好的。无论如何, sprintf 方法和您的回答都有助于让我明白我应该尝试另一种方式。我接受你的回答。我想我会选择这个 (gis.stackexchange.com/questions/138611/…)。
猜你喜欢
  • 2022-01-23
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多