用空格而不是作为字符类导入的点来协调数据:如何清理?

问题描述 投票:0回答:1

对于复杂的帖子提前表示歉意;这是一个(非常令人沮丧的)问题,我已经困扰了很长一段时间了。

我有一个数据集,正处于清理的最后步骤。我试图克服的最后一个障碍与坐标信息的输入方式有关 - 经度和纬度的格式是伪 DMS 和十进制形式的混合,以及一些常见的混乱。这是经度列的示例:

"096 34 01.63" "096 35 46.93" "96.48.838" "19* 9 41.715" "19 9 15.922"

如您所见,秒数远远超过 60、

"19* 9 41.715" "19 9 15.922"
中存在杂散小数、不正确的度值(19 9 而不是 -96)、标牌问题等

这两列的类别都是字符。我尝试将类更改为数字,因为我必须对秒进行一些算术才能修复它们(见上文),但这引入了 NA;我认为这是条目中空格的结果。作为参考,这就是示例应该在完成初始步骤后的样子:

"096:34:01.63" "096:35:46.93" "96:48:838" "199:41:715" "199:15:922"

这就是我完全清洁后的样子:

"-96:34:1.63" "-96:35:46.93" "-96:48:13.97" "-96:41:11.91" ""-96:15:15.36"

有什么方法可以在不引入 NA 的情况下完成将列转换为数字类的初始步骤吗?

r data-cleaning
1个回答
0
投票

首先,我假设您所需的输出中的一些差异是拼写错误:负数(不确定)和 19-to-199-to-96。我认为以下结果是一致的。

  1. 消除

    *
    噪音。

  2. 标准化太多点,每个字符串只允许一个。例如,

    "96.48.838"
    ->
    "96 48.838"

    gsub("\\.(?=[^.]*[.])", " ", "11.22.33.44.55", perl=TRUE)
    # [1] "11 22 33 44.55"
    
  3. 将DM转换为DMS;例如,

    "96 48.838"
    ->
    "96 48 50.28"
    ,因为
    0.838
    分钟是
    50.28
    秒。

  4. (假设)将

    0
    -填充添加到度/分钟,将秒限制为 3 位小数。

vec <- c("096 34 01.63", "096 35 46.93", "96.48.838", "19* 9 41.715", "19 9 15.922")
gsub("*", "", vec, fixed=TRUE) |>
  gsub("\\.(?=[^.]*[.])", " ", x = _, perl=TRUE) |>
  strsplit(" ") |> 
  sapply(function(X) {
    X <- as.numeric(X)
    if (length(X) == 2) X <- c(floor(X[1:2]), X[2] %% 1 * 60)
    paste(c(sprintf("%02.0f", X[1:2]),
            sprintf("%02.3f", X[3])),
          collapse = ":")
  })
# [1] "96:34:1.630"  "96:35:46.930" "96:48:50.280" "19:09:41.715" "19:09:15.922"
© www.soinside.com 2019 - 2024. All rights reserved.