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
Call rlang::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
我是不是把整件事都搞错了?任何帮助将不胜感激。我希望我的问题足够清楚,如果不是,我很抱歉(我是新手)。
- 我无法重现您的错误消息,但请尝试 prob %>% mutate_all(funs(str_replace_all(.,'[\\\\.,]’,”))) 删除所有 . 和 ,。在大多数 R 正则表达式情况下,您需要将转义的 \\\\ 加倍,如果您想做任何复杂的事情,mutate_all 通常需要一个函数的 funs() package器。
- prob 是您发布 dput 的数据框吗?
- @CriminallyVulgar 成功了!!!非常感谢你。我如何为您提供快速有效帮助的道具?
- 嗯,它可以工作,但现在我的变量是字符:/我试图将所有内容package在 as.numeric() 中,但收到一条错误消息: prob <- prob %>% as.numeric(mutate_all(funs(str_replace_all(.,’ [\\\\\\\\.,]’,”)))) UseMethod(“tbl_vars”) 中的错误:没有适用于”tbl_vars”的方法应用于”fun_list”类的对象
- @camille,正确!
- @Andrea不需要,我指出这是一个小调整。就您的整体需求而言,下面的答案可以更充分地满足它们!
您需要先转换为字符,然后替换,然后再转换回数字:
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 |
感谢@camille stringr::str_remove_all 的建议。
我还想到 R 可能会在您不打算在尾随零的情况下进行舍入。在您的示例中以 C1_3_99 的第一个条目 5.62 为例。这可能需要 5,620(如果句点是千位分隔符),而不是我的第一个解决方案给出的 562。您可以使用格式化程序和深思熟虑的除法来处理这个问题:
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 |
格式化程序确保小数点后有 3 位数字,但会为没有小数点的数字添加三个 0(从此处提取的格式代码),因此如果不存在小数点,则除以 1000。欢迎在这里提供更优雅的解决方案。
- 作为快捷方式,stringr::str_remove_all 与 stringr::str_replace_all 相同,但替换为空字符
- 太感谢了!!这太棒了,完全解决了问题,同时仍然允许我将数据用作数字。很完美,非常感谢!
- 没问题 – 为了完整起见,我对某些边缘情况进行了小更新。我不确定它们是否适用于您的情况,但无论如何都想做一点挖掘。
尝试使用 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 |
我希望这会有所帮助!
- 就像我们提醒提问者不要在图像中放置代码或打印输出文本一样,如果提问者可以这样做,这将很有帮助
- 此外,现在您有一个矩阵而不是数据框,并且保留其数据的结构是 OP 关心的一件事
来源:https://www.codenong.com/55026965/