在 x 位 R 后加小数
Add decimal after x digit R
我有一个带有坐标 (SWEREF_99, proj 3006) 的数据框,我意识到很多坐标的格式有误。
对于北坐标,它们总是在逗号前有七位数字,而东坐标在逗号前有六位数字,然后是十进制数字。喜欢:6789654.234(北)。但是,我的坐标看起来像这样; 6789654234。这意味着我要在数字4和2之间输入一个comma/dot。
我试过 formatC
和 format
但是当我使用它们时我添加了多个逗号,例如 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
我有一个带有坐标 (SWEREF_99, proj 3006) 的数据框,我意识到很多坐标的格式有误。
对于北坐标,它们总是在逗号前有七位数字,而东坐标在逗号前有六位数字,然后是十进制数字。喜欢:6789654.234(北)。但是,我的坐标看起来像这样; 6789654234。这意味着我要在数字4和2之间输入一个comma/dot。
我试过 formatC
和 format
但是当我使用它们时我添加了多个逗号,例如 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