如何找到小于 2 的小数位并在 R 中用零填充它们

How to find decimal places lower than 2 and fill them with zeros in R

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

我想将图像中的 RGB 信息合并到 3d 数据中。我想使用两个数据集的 x y 坐标(它们在同一坐标系中)。 我根据在 Whosebug 中找到的代码片段编写了一个脚本,但我需要实现我的整个代码(来源是 1, 2, and 3)。

问题是两个文件中的xy坐标有不同的精度(小数)。数据集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

LIDAR(已更改,并添加了 'xy' 列用于加入)

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

编辑 2

我以某种方式设法用 counting <- sapply(lidar$x, decimalplaces) 检索了我的 'lidar' 变量(数据集 B)的所有 x 和 y 中的位数 在上面的示例(LIDAR-original)中,这将为第一 (x) 列提供 [0 0],为第二 (y) 列提供 [0 1]。我应该能够在我的 x y 数据集中找到每一行,其值为 0 或 1 作为数字(不是 2)并用 0 填充,就像在上面的 LIDAR-altered 中一样。

我不明白为什么要用零填充。如果坐标是 class 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)