在 x 位 R 后加小数

Add decimal after x digit R

我有一个带有坐标 (SWEREF_99, proj 3006) 的数据框,我意识到很多坐标的格式有误。

对于北坐标,它们总是在逗号前有七位数字,而东坐标在逗号前有六位数字,然后是十进制数字。喜欢:6789654.234(北)。但是,我的坐标看起来像这样; 6789654234。这意味着我要在数字4和2之间输入一个comma/dot。

我试过 formatCformat 但是当我使用它们时我添加了多个逗号,例如 678.965.423.4 或者只是在小数之后添加零。

测试 <- 格式(data$North,7,nsmall = 0)

这是一个带有虚坐标的数据框,但它很好地描述了我的数据。

data <- data.frame(North = c(678645345, 675836578, 6573645.786), East = c(354674.47, 37465434, 4263546))

如你所见,我的一些坐标看起来不错,北坐标有七位,东坐标有六位。所以这些我不想改变,但只有那些不包含逗号的。

有没有人遇到同样的问题?

在这种情况下,大多数情况下将数字作为字符串进行操作会更容易。这应该可以解决您的问题:

data <- data.frame(North = c(678645345, 675836578, 6573645.786), East = c(354674.47, 37465434, 4263546))

insertComma <- function(data,commaPosition)
{
  data.str <- as.character(data)
  data.comma <- ifelse(substr(data.str,commaPosition,commaPosition) != ".",paste0(substr(data.str,1,commaPosition - 1),".",
                                                                                  substr(data.str,commaPosition,nchar(data.str))),data.str)
  return(data.comma)
}
commaPositions <- c(8,7)

sapply(seq_len(ncol(data)),function(col) insertComma(data[,col],commaPositions[col]))

     [,1]          [,2]       
[1,] "6786453.45"  "354674.47"
[2,] "6758365.78"  "374654.34"
[3,] "6573645.786" "426354.6" 

试试这个:

within(data, {
  North = North / 10 ^ (nchar(trunc(North)) - 7L)
  East = East / 10 ^ (nchar(trunc(East)) - 6L)
})

您可以使用正则表达式在特定位置插入小数点:

transform(data, North = sub('(.{7})\.?(.*)', '\1.\2', North), 
                East = sub('(.{6})\.?(.*)', '\1.\2', East))

#        North      East
#1  6786453.45 354674.47
#2  6758365.78 374654.34
#3 6573645.786  426354.6

我们将数据分成 2 个捕获组。

第一个捕获组(.{7}) - 捕获前 7 个字符

\.? - 一个可选的小数位(如果存在)将被忽略。

第二个捕获组 ((.*)) 就是之后的所有内容。

我们 return 两个带有反向引用的捕获组在它们之间添加 "." ('\1.\2')。

相同的逻辑适用于 East 列。

这似乎有效,使用 tidyverse 和 base-R 的基本函数(grepl、substr、粘贴、变异、case_when)。如果你对正则表达式不满意,你可以试试这个:

library(dplyr)

data <- data.frame(North = c(678645345, 675836578, 6573645.786), East = c(354674.47, 37465434, 4263546))

data %>%
  mutate(North = case_when(grepl(".", as.character(North), fixed = TRUE) ~ as.character(North),
                           TRUE ~ paste0(substr(North,1,7),".",substr(North,8,nchar(North)))),
         East = case_when(grepl(".", as.character(East), fixed = TRUE) ~ as.character(East),
                          TRUE ~ paste0(substr(East,1,6),".",substr(East,7,nchar(East)))))

输出:

        North      East
1  6786453.45 354674.47
2  6758365.78 374654.34
3 6573645.786  426354.6