我有一个来自世界各地的参与者的大型数据集。其中一些参与者使用点/句号/逗号输入数据以指示千位分隔符,但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(替换),:参数不是原子向量;强制
我接近整件事了吗?任何帮助将不胜感激。我希望我的问题很清楚,如果不是,我道歉(我是新手)。
你想要转换为字符,然后替换,然后转换回数字:
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。这里有更优雅的解决方案。
试着使用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
我希望这有帮助!