【问题标题】:Remove dots from data column从数据列中删除点
【发布时间】:2018-09-04 20:57:11
【问题描述】:

我是处理 R 和使用字符串的初学者。 我一直在尝试从数据中删除句点,但不幸的是我找不到解决方案。

这是我在数据框df 中处理的数据:

df <- read.table(text = " n   mesAno          receita
                 97   1/2009 3.812.819.062,06
                 98   2/2009 4.039.362.599,36
                 99   3/2009 3.652.885.587,18
                 100  4/2009 3.460.247.960,02
                 101  5/2009 3.465.677.403,12
                 102  6/2009 3.131.903.622,55
                 103  7/2009 3.204.983.361,46
                 104  8/2009 3.811.786.009,24
                 105  9/2009 3.180.864.095,05
                 106 10/2009 3.352.535.553,88
                 107 11/2009 5.214.148.756,95
                 108 12/2009 4.491.795.201,50
                 109  1/2010 4.333.557.619,30
                 110  2/2010 4.808.488.277,86
                 111  3/2010 4.039.347.179,81
                 112  4/2010 3.867.676.530,69
                 113  5/2010 6.356.164.873,94
                 114  6/2010 3.961.793.391,19
                 115  7/2010    3797656130.81
                 116  8/2010    4709949715.37
                 117  9/2010    4047436592.12
                 118 10/2010    3923484635.28
                 119 11/2010    4821729985.03
                 120 12/2010    5024757038.22", 
header = TRUE, 
stringsAsFactors = TRUE)

我的目标是将receita 列转换为数字,因为它被存储为因子。但是像 as.numeric(as.factor(x)) 这样的转换函数在 97:114 间隔内不起作用(它强制转换为 NA)。

我想这是因为此列中分隔十亿/百万/千的周期。 仅当我在 115:120 中具有 3812819062.06 之类的内容时,上述转换函数才会起作用。

我尝试改变数据集添加另一列和建模。 我真的不知道我在做什么是否正常,但我也尝试将异常数字提取到变量中,并对其应用 sub/gsub 但没有成功。

是否有一些直接的方法可以做到这一点,即指示它删除第一次出现的 2 个 '.'然后用“。”替换逗号? 我非常有信心我需要的功能是gsub,但我很难找到正确的用法。任何帮助将不胜感激。

编辑:我使用dplyr::mutate() 的方法。丑陋但有效。

df <- df %>% 
mutate(receita_temp = receita) %>% 
mutate(dot_count = str_count(receita, '\\.')) %>% 
mutate(receita_temp = ifelse(dot_count == 3, 
                             gsub('\\.', '', as.factor(receita_temp)), 
                             gsub('\\,', '.',as.factor(receita_temp))
                             )) %>% 
mutate(receita_temp = ifelse(dot_count == 3,
                             gsub('\\,', '.',as.factor(receita_temp)),
                                  receita_temp)) %>% 
select(-c(dot_count, receita)) %>% 
rename(., receita = receita_temp)

【问题讨论】:

  • 我确信有一个函数可以更漂亮地执行此操作,但您始终可以在前 114 行中使用两次gsub。代替 ”。”为“”第一次,“”为“。”第二个,你会留下与你以后的条目相匹配的数字。只要确保你没有将它应用到整个列,否则你会弄乱那些已经正确格式化的列
  • 请添加您尝试改变文本的代码。
  • @WiktorStribiżew,作为编辑添加。

标签: r regex


【解决方案1】:

我正在使用正则表达式和一些stringr 函数来删除所有句点,除了后跟两位数字和字符串结尾的句点。这样,在3.811.786.009,24 中表示分隔的句点将被删除,但在4821729985.03 中表示小数开始的句点则不会。使用 str_remove_all 而不是 str_remove 让我不必担心重复删除匹配项或它的扩展程度。然后用句点替换剩余的逗号,并使其成为数字。

library(tidyverse)

df2 <- df %>%
  mutate(receita = str_remove_all(receita, "\\.(?!\\d{2,}$)") %>% 
           str_replace_all(",", ".") %>%
           as.numeric())

print(head(df2), digits = 12)
#>     n mesAno       receita
#> 1  97 1/2009 3812819062.06
#> 2  98 2/2009 4039362599.36
#> 3  99 3/2009 3652885587.18
#> 4 100 4/2009 3460247960.02
#> 5 101 5/2009 3465677403.12
#> 6 102 6/2009 3131903622.55

reprex package (v0.2.0) 于 2018 年 9 月 4 日创建。

【讨论】:

    【解决方案2】:

    您可以使用以下内容: 首先创建一个用于替换的函数:

    repl = function(x)setNames(c("","."),c(".",","))[x]
    

    此函数接受".""," 并分别返回""'.'

    现在用这个函数替换

    stringr::str_replace_all(as.character(df[,3]), "[.](?!\\d+$)|,", repl)
    
    [1] "3812819062.06" "4039362599.36" "3652885587.18" "3460247960.02" "3465677403.12" "3131903622.55"
    [7] "3204983361.46" "3811786009.24" "3180864095.05" "3352535553.88" "5214148756.95" "4491795201.50"
    [13] "4333557619.30" "4808488277.86" "4039347179.81" "3867676530.69" "6356164873.94" "3961793391.19"
    [19] "3797656130.81" "4709949715.37" "4047436592.12" "3923484635.28" "4821729985.03" "5024757038.22"
    

    当然,您可以完成其余的工作。即调用as.numeric()等。

    要在基础 R 中执行此操作:

    sub(',','.',gsub('[.](?!\\d+$)','',as.character(df[,3]),perl=T))
    

    或者如果您知道数据中 ., 的确切数量,您可以这样做

    a = as.character(df[,3])
    regmatches(a,gregexpr('[.](?!\\d+$)|,',df[,3],perl = T)) = list(c("","","","."))
    a
    

    【讨论】:

      【解决方案3】:
      df$num <- as.numeric(sapply(as.character(si), function(x) gsub("\\,","\\.",ifelse(grepl("\\,", x), gsub("\\.","",x),x))))
      

      应该可以解决问题。

      首先,该函数搜索带有“,”的行,删除“。”在这些行中,最后它将所有出现的“,”转换为“。”,以便可以毫无问题地将其转换为数字。

      使用print(df$num, digits = 12) 查看您的数据,保留两位小数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多