【问题标题】:A regular expression to filter out repetitive numbers for R data frame columns用于过滤掉 R 数据框列的重复数字的正则表达式
【发布时间】:2021-05-19 23:35:24
【问题描述】:

我有一个包含许多列和行的数据框,我需要根据两列(Lat 和 Lon)的值进行过滤。我需要一个正则表达式

  1. 删除 Lat 或 Lon 列没有至少三位小数的任何行。所以第一行(人类)将被过滤,因为即使 Lon 有三位小数,但 Lat 没有。
  2. 删除小数位多余的任何行。我所说的冗余是指三个相同数量的重复一直持续到最后。但如果冗余在小数点后第三位开始,那没关系。如果冗余最终后面跟着一个不同的数字,那也没关系。
Type <-c("human","camera","ebird","museum", "specimen", "gbif")
Lat <- c(34.67, 34.66,34.6666666, 34.666582, 34.56666, 34.586666)
Lon <- c(9.888,9.88,9.8761,9.888064, 9.78888,9.318888)
x = data.frame(cbind(Type,Lat,Lon))

下面是每行在正则表达式下的表现:

  1. 失败,因为 Lat 只有两位小数,尽管 Lon 通过了。
  2. 失败,因为两行只有两位小数
  3. 失败,因为 Lat 重复相同的值,从第一个小数位开始,重复到数字的末尾。
  4. 通过正则表达式
  5. 失败,因为重复数值从小数点后第二位开始,并一直持续至少 3 次重复直到结束
  6. 通过正则表达式

因此,此正则表达式过滤器的结果数据框将是:

Type <-c("museum","gbif")
Lat <- c(34.666582, 34.586666)
Lon <- c(9.888064, 9.318888)
x = data.frame(cbind(Type,Lat,Lon))

【问题讨论】:

  • 您已将latlon 存储为数字。如果某些纬度/经度存储为 34.66034.60034.000 在所有这些情况下,额外的 0 将被自动截断。在所有这些情况下,您是要保留这些还是过滤掉?
  • 34.660 应该通过这个正则表达式 ex。如果 Lat 和 Lon 列都有尾随零(并且仅适用于数字 0,不适用于其他数字),我们是否可以修改以使 34.600 失败?因此,如果 Lat 是 34.600 而 Lon 是 9.300,它应该会失败。 34.000 会失败,因为 0 重复了三次,三个重复的零之后没有任何内容。
  • 1) 为什么你指定34.66(纬度第二行)失败呢?当34.66 == 34.660?为什么假设0 不存在?
  • 我要解释的只是用这个Lat &lt;- c(34.670, 34.660,34.6666666, 34.666582, 34.56666, 34.586666) 更改您的Lat 列,然后检查x 的输出
  • 因为这些是实际的纬度和经度值,而 34.660 是经度的合法值,在我从中获取此数据帧的数据集中,它比 34.66 更准确。因此,如果零明确表示在小数点后第三位,我相信它是一个准确的坐标。我正在过滤掉不准确的坐标。我不相信具有不可能重复的十进制值或大量重复零的坐标。对于每个纬度/经度条目,我还需要至少三个明确写入的十进制值。

标签: r regex dataframe filter


【解决方案1】:

下面的函数将输出您想要的所需数据帧。它满足您上述所有要求。

check.expressions <- function(data){
  data$pass <- FALSE
  for(i in 1:nrow(data)){
    if(nchar(str_extract(x$Lon[i], "(?<=\\.).*")) < 3 | nchar(str_extract(x$Lat[i], "(?<=\\.).*")) < 3){
     next 
    } else {
      unlist(str_split(str_extract(x$Lon[i], "(?<=\\.).*" ), "")) -> lon
      unlist(str_split(str_extract(x$Lat[i], "(?<=\\.).*" ), "")) -> lat
      if(lon[1] == lon[2] && lon[2] == lon[3]){
        if(length(lon) > 3){
          if(lon[3] != lon[length(lon)]){
            data$pass[i] <- TRUE
            next
          } else {
            next
          }
        }
        next
      }
      if(lat[1] == lat[2] && lat[2] == lat[3]){
        if(length(lat) > 3){
          if(lat[3] != lat[length(lat)]){
            data$pass[i] <- TRUE
            next
          } else {
            next
          }
        }
        next
      }
      if(length(lon) > 4){
        if(lon[2] == lon[3] && lon[3] == lon[4]){
          if(lon[4] != lon[length(lon)]){
            data$pass[i] <- TRUE
            next
          } else {
            next
          }
        }
      }
      if(length(lat) > 4){
        if(lat[2] == lat[3] && lat[3] == lat[4]){
          if(lat[4] != lat[length(lat)]){
            data$pass[i] <- TRUE
            next
          }
        }
      }
      data$pass[i] <- TRUE
    }
  }
  data[data$pass == TRUE, ] -> data
  return(data)
}

函数调用只是:

check.expressions(x) -> x.out

会产生:

> check.expressions(x) -> x.out
> x.out
    Type       Lat      Lon pass
4 museum 34.666582 9.888064 TRUE
6   gbif 34.586666 9.318888 TRUE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多