【问题标题】:R: Extract first number despite irregular delimiter from a junk dataR:从垃圾数据中提取第一个数字,尽管分隔符不规则
【发布时间】:2022-04-24 16:10:42
【问题描述】:

我正在处理一个数据框df,其中包含数千行垃圾数据,尽管分隔符不规则,但要在其中提取第一个数字:

dummy_numbers = c(\"70210813000 70210862354\",
\"(234) 641-9690\", \"ren  23465726375 Finney\",
\"234 0225 7583 ALT 031 026 66542\", \"omega\",
\"(034) 319-6427\", \"(034)3263802\", \"(034)3128548\",
\"Mat: 030791272113 / 03040752983\")

df <- data.frame(dummy_numbers)

> df
                    dummy_numbers
1         70210813000 70210862354
2                  (234) 641-9690
3         ren  23465726375 Finney
4 234 0225 7583 ALT 031 026 66542
5                           omega
6                  (034) 319-6427
7                    (034)3263802
8                    (034)3128548
9 Mat: 030791272113 / 03040752983

预期结果是:

> df
          dummy_numbers
1         70210813000
2         2346419690
3         23465726375
4         23402257583
5         NA
6         0343196427
7         0343263802
8         0343128548
9         030791272113

删除字母、标点符号、空格、破折号和所有非数字的想法并没有产生预期的结果。我认为这是由于无法处理不规则的分隔符。

> df %>% dplyr::mutate(dummy_numbers = gsub(\"[- ./)(+]|[a-zA-Z]*:?\",\"\", dummy_numbers))
            dummy_numbers
1  7021081300070210862354
2              2346419690
3             23465726375
4  2340225758303102666542
5                        
6              0343196427
7              0343263802
8              0343128548
9 03079127211303040752983

使用 strex 包中的 str_first_number() 函数的想法也没有产生预期的结果。

library(strex)
> df %>% dplyr::mutate(dummy_numbers = str_first_number(dummy_numbers))
  dummy_numbers
1   70210813000
2           234
3   23465726375
4           234
5            NA
6            34
7            34
8            34
9   30791272113

任何帮助将不胜感激。

  • 不是答案,但您有许多不同的电话号码类型,包括一些非 10 位美国电话号码的非标准号码。如果您可以在将这些数据带入 R 之前在源头对其进行规范化,那么请这样做。
  • 是的,我也认为在提取之前应该进行一些数据清理。 Stringi\ 的函数给出了更好的结果,但仍然失败。 stri_extract_first_regex(df$dummy_numbers, \"[0-9]+\")

标签: r regex digits grepl


【解决方案1】:

根据您给出的示例,您可以将问题一分为二。

首先处理没有字母字符和括号或减号的字符串。

然后做其他的。不确定这是否适用于您数据集中的所有值。您可能需要添加更多规则并使用 case_when 或类似名称。

library(stringr)

data.frame(dummy_numbers=
  ifelse(!grepl("[[:alpha:]()-]", df$dummy_numbers),
    str_extract(df$dummy_numbers, "[[:digit:]]+"),
    trimws(str_extract(gsub("[ ()-]","", 
             df$dummy_numbers), "[[:digit:]]+"))))
  dummy_numbers
1   70210813000
2    2346419690
3   23465726375
4   23402257583
5          <NA>
6    0343196427
7    0343263802
8    0343128548
9  030791272113

【讨论】:

  • 非常感谢。您的代码是朝着预期结果迈出的重要一步,尽管这并不适用于数据集中的所有值。其他规则仍需添加
猜你喜欢
  • 1970-01-01
  • 2014-06-12
  • 2020-02-04
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 2017-05-07
  • 2015-07-05
  • 2013-06-24
相关资源
最近更新 更多