删除整个数据框中的句点/点

时间:2019-03-06 15:43:24

标签: r dplyr stringr

我有一个庞大的数据集,有来自世界各地的参与者。其中一些参与者使用点/句点/逗号输入数据以指示千位分隔符,但是R会将它们读取为逗号,这完全歪曲了我的数据... 例如1234变成1,234。

我要删除所有点/句点/逗号。我的数据完全由整数组成,所以任何地方都不应该有小数。

我尝试使用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(string,pattern,fix_replacement(replacement),中:     参数不是原子向量;胁迫

我把整个事情都弄错了吗?任何帮助将不胜感激。我希望我的问题很清楚,如果不是这样的话,我深表歉意(我是新来的)。

2 个答案:

答案 0 :(得分:2)

您将要转换为字符,然后替换,然后转换回数字:

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

针对stringr::str_remove_all的建议,致谢@camille。

我还想到,当您不希望R尾随零时,R可能会四舍五入。以您的示例中的C1_3_99的第一项为5.62。这可能需要是5,620(如果期间是千位分隔符),而不是我的第一个解决方案给出的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位数字,但是会为不带小数点的数字(formatting code yanked from here)加上三个0,因此,如果不存在小数点,则除以1000。欢迎在此提供更优雅的解决方案。

答案 1 :(得分:0)

只需尝试使用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

我希望这会有所帮助!