Удалить точки / точки во всем фрейме данных - PullRequest
1 голос
/ 06 марта 2019

У меня большой набор данных с участниками со всего мира.Некоторые из этих участников вводили данные, используя точки / точки / запятые, чтобы указать тысячи разделителей, но R считывает их как запятые, которые полностью искажают мои данные ... например, 1234 становятся 1234.

Я хочу удалить все точки /периодов / запятых.Мои данные полностью состоят из полных чисел, поэтому нигде не должно быть десятичных знаков.

Я пытался использовать stringr, но не могу понять.Вот (я надеюсь) воспроизводимый пример с небольшой выборкой моих данных:

structure(
  list(
    chnb = c(10L, 35L, 55L),
    B1_1_77 = c(117.586,
                4022, 4.921),
    C1_1_88 = c(NA, 2206, 1.111),
    C1_1_99 = c(6.172,
                1884, 0),
    C1_3_99 = c(5.62, 129, 0)
  ),
  row.names = c(NA,-3L),
  class = c("tbl_df",
            "tbl", "data.frame")
)

Я попробовал это:

prob1 <- prob %>% str_replace_all('\\.', '')

, что дает мне это:

> prob
[1] "c(10, 35, 55)"         "c(117586, 4022, 4921)" "c(NA, 2206, 1111)"    
[4] "c(6172, 1884, 0)"      "c(562, 129, 0)"  

Он действительно удалил точки, но дал мне простой список и полностью потерял мою структуру данных.Поиск в Интернете показал, что я сделал это:

prob1 <- prob %>% mutate_all(list(str_replace(., '\\.', '')))

, но я получаю сообщение об ошибке:

Ошибка: .fn должна быть длиной в 1 строку. Вызовите rlang::last_error(), чтобы увидетьобратная трассировка Дополнительно: предупреждающее сообщение: в stri_replace_first_regex (строка, шаблон, fix_replacement (замена),: аргумент не является атомным вектором;очень признателен. Я надеюсь, что мой вопрос достаточно ясен, мои извинения, если это не так (я новичок в этом).

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

Вы хотите преобразовать в символ, затем заменить, а затем преобразовать обратно в числовой:

library(tidyverse)
dat %>%
  mutate_all(~as.numeric(str_remove_all(as.character(.x), '\\.')))

# A tibble: 3 x 5
   chnb B1_1_77 C1_1_88 C1_1_99 C1_3_99
  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    10  117586      NA    6172     562
2    35    4022    2206    1884     129
3    55    4921    1111       0       0

Кредит @camille за предложение stringr::str_remove_all.

Это также произошлодля меня, что R может округляться, когда вы не собираетесь это в случае конечного нуля.Возьмите первую запись C1_3_99 в вашем примере, 5.62.Возможно, это должно быть 5620 (если период был разделителем тысяч), а не 562, как показывает мое первое решение.Вы можете справиться с этим, используя средство форматирования и продуманное деление:

dat %>%
  mutate_all(~as.numeric(str_remove_all(format(round(.x, 3), nsmall = 3), '\\.')) / 
               if_else(str_detect(.x, "\\."), 1, 1000))

# A tibble: 3 x 5
   chnb B1_1_77 C1_1_88 C1_1_99 C1_3_99
  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    10  117586      NA    6172    5620
2    35    4022    2206    1884     129
3    55    4921    1111       0       0
Warning message:
In (function (..., .x = ..1, .y = ..2, . = ..1)  :
  NAs introduced by coercion

Модуль форматирования гарантирует, что после десятичного разделителя есть 3 цифры, но добавит три 0 для чисел без десятичного числа ( код форматирования, полученный изздесь ), поэтому вы делите на 1000, если нет десятичного числа.Более элегантные решения здесь приветствуются.

0 голосов
/ 06 марта 2019

Просто попробуйте использовать sapply:

df <-  structure(
  list(
    chnb = c(10L, 35L, 55L),
    B1_1_77 = c(117.586,
                4022, 4.921),
    C1_1_88 = c(NA, 2206, 1.111),
    C1_1_99 = c(6.172,
                1884, 0),
    C1_3_99 = c(5.62, 129, 0)
  ),
  row.names = c(NA,-3L),
  class = c("tbl_df",
            "tbl", "data.frame")
)

sapply(df, function(v) {as.numeric(gsub("\\.","", as.character(v)))})

Это результат:

     chnb B1_1_77 C1_1_88 C1_1_99 C1_3_99
[1,]   10  117586      NA    6172     562
[2,]   35    4022    2206    1884     129
[3,]   55    4921    1111       0       0

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...