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

问题描述 投票:1回答:2

我有一个来自世界各地的参与者的大型数据集。其中一些参与者使用点/句号/逗号输入数据以指示千位分隔符,但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中(字符串,模式,fix_replacement(替换),:参数不是原子向量;强制

我接近整件事了吗?任何帮助将不胜感激。我希望我的问题很清楚,如果不是,我道歉(我是新手)。

r dplyr stringr
2个回答
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

感谢@camille提出的stringr::str_remove_all建议。

我也想到,当你不打算在尾随零的情况下,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)将添加3个0,因此如果没有小数,则除以1000。这里有更优雅的解决方案。


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

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.