Remove periods/dots in entire data frame
我有一个包含来自世界各地的参与者的大型数据集。其中一些参与者使用点/句点/逗号输入数据来表示千位分隔符,但 R 将它们读取为逗号,这完全扭曲了我的数据......
例如1234 变成 1,234。
我想删除所有的点/句点/逗号。我的数据完全由完整的数字组成,因此任何地方都不应该有任何小数。
我尝试使用 stringr,但不太明白。这是一个(我希望)可重复的示例,其中包含我的一小部分数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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") ) |
我试过这个:
1 | prob1 <- prob %>% str_replace_all('\\\\.', '') |
这给了我这个:
1 2 3 | > prob [1]"c(10, 35, 55)" "c(117586, 4022, 4921)""c(NA, 2206, 1111)" [4]"c(6172, 1884, 0)" "c(562, 129, 0)" |
它确实删除了点,但它给了我一个简单的列表,并且完全丢失了我的数据结构。在线搜索建议我这样做:
1 | prob1 <- prob %>% mutate_all(list(str_replace(., '\\\\.', ''))) |
但我收到一条错误消息:
Error:
.fn must be a length 1 string
Callrlang::last_error() to see a backtrace
In addition: Warning message:
In stri_replace_first_regex(string, pattern, fix_replacement(replacement), :
argument is not an atomic vector; coercing
我是不是把整件事都搞错了?任何帮助将不胜感激。我希望我的问题足够清楚,如果不是,我很抱歉(我是新手)。
您需要先转换为字符,然后替换,然后再转换回数字:
1 2 3 4 5 6 7 8 9 10 | 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
我还想到 R 可能会在您不打算在尾随零的情况下进行舍入。在您的示例中以
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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。欢迎在这里提供更优雅的解决方案。
尝试使用 sapply:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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)))}) |
这是结果:
1 2 3 4 | 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 |
我希望这会有所帮助!