Converter Numeros em formato de texto

Caros, bom dia!

Estou tentando comverter uma coluna de numeros que estáem formato de texto.
Esses numeros estão com formato brasileiro, portanto com código abaixo tentei converter em formato americado para depois formatar para numeros.

 invest  |> 
     dplyr::select(lancamento)  |>
             dplyr::mutate( mov = ifelse( 
                                 (stringr::str_sub(string = lancamento, 
                                 start = 1, end = 1) =="-"), 
                            yes = "Negativo", no = "Positivo") ,
              lancamento  = stringr::str_remove( lancamento, pattern = "-"),
              lancamento =  stringr::str_replace( string = lancamento, pattern = "\\,", "*"),
              lancamento =  stringr::str_replace( string = lancamento, pattern = "\\.", ",") ,
              lancamento =  stringr::str_replace( string = lancamento, pattern = "\\*", ".") |> 
                            stringr::str_trim(side = "both") ) |> 
     dplyr::mutate( valor = lancamento |> as.numeric())

Qual problema?

Uma parte converteu com sucesso, outra não, principalmente os negativos.
O R emitiu uma mensagem de aviso:

A tibble: 233 x 3

lancamento mov valor

1 57.60 Positivo 57.6
2 250.00 Positivo 250
3 113.40 Positivo 113.
4 135.89 Positivo 136.
5 47.50 Positivo 47.5
6 26.70 Positivo 26.7
7 184.10 Positivo 184.
8 58.20 Positivo 58.2
9 39.65 Positivo 39.6
10 59.52 Positivo 59.5

… with 223 more rows

Warning message:
Problem while computing valor = as.numeric(lancamento).
i NAs introduced by coercion

Fiz varias tentativas e pesquisa sem sucesso.

Alguem já teve problema parecido que possa ajudar?

Compartilho a base para reproduzir o resultado.

Muito Obrigado!

Joel,

Olhando o seu código, eu tenho um palpite sobre o problema. Em primeiro lugar, vocês está complicando o processo de conversão mais do que o necessário; o R não precisa da divisão entre as centenas, então era mais fácil você simplesmente remover os pontos. Além disso, a as.numeric() não tem problema com negativos ou espaços extras, ou seja, você também não precisa daquele ifelse() nem daquele stringr::str_trim().

Enfim, agora sobre o problema de fato:

  1. Eu acho que você deveria estar usando stringr::str_replace_all() ao invés da stringr::str_replace(). A primeira substitui todas as ocorrências de um padrão, enquanto a segunda substitui só a primeira ocorrência. Nesse caso pode ser que você esteja deixando pontos adicionais perdidos que quebram a conversão.

  2. Adicionalmente, a conversão só funciona se não houver espaço algum entre o sinal de menos e o resto do número.

Para debugar esse tipo de problema, é importante você criar uma coluna parcial, com o resultado de cada transformação que você faz em lancamento. Assim você pode testar o seu algoritmo passo a passo.

Se meu palpite estiver correto, você deve conseguir usar o código abaixo para fazer a sua transformação:

invest <- tibble::tibble(
  lancamento = c("  100.000,00  ", "-   300,50", " - 123.456.789,00   ")
)

invest |>
  dplyr::mutate(
    valor = lancamento |>
      stringr::str_remove_all("\\.") |>
      stringr::str_replace(",", ".") |>
      stringr::str_replace("- +", "-") |>
      as.numeric()
  )
#> # A tibble: 3 × 2
#>   lancamento                   valor
#>   <chr>                        <dbl>
#> 1 "  100.000,00  "           100000 
#> 2 "-   300,50"                 -300.
#> 3 " - 123.456.789,00   " -123456789

Created on 2022-05-07 by the reprex package (v2.0.1)

P.S.: Não consegui acessar a tabela porque você precisa liberar isso individualmente. Seria mais fácil colocar algumas linhas dela na pergunta, assim qualquer um pode tentar ajudar.

2 curtidas

Woooww Top demais Caio!

Muito mais simples que imaginava.

Simplicidade é tudo e no R e mais ainda.

Amo cada dia mais essa linguagem!

Muito Obrigado pela ajuda!