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

时间:2016-01-11 14:41:31

标签: r join raster geotiff lidar

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

我想将图像中的RGB信息合并到3d数据中。我想要使​​用两个数据集的x y坐标(它们在同一个坐标系中)。 我编写了一个受stackoverflow中的代码片段启发的脚本,但我需要实现我的整个代码(源代码为123)。

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

考虑到我的datset有> 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)的样子,以及用零填充它之后的样子。

LIDAR (原创)

x     y     z
12    9     87
11    23.4  100

LIDAR (已更改,并且添加了&#39; xy&#39;列用于加入)

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

编辑2

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

1 个答案:

答案 0 :(得分:1)

我不明白为什么你需要用零填充。如果坐标属于类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) 进行舍入(这应该避免浮点精度问题),您应该能够通过它们进行合并。像这样:

typedef struct _String {
            char* str;
            char* (*ToUpper) (void);
         } String;