移除千位分隔符

6

我导入了一个Excel文件,得到了一个类似于这样的数据框

structure(list(A = structure(1:3, .Label = c("1.100", "2.300", 
"5.400"), class = "factor"), B = structure(c(3L, 2L, 1L), .Label = c("1.000.000", 
"500", "7.800"), class = "factor"), C = structure(1:3, .Label = c("200", 
"3.100", "4.500"), class = "factor")), .Names = c("A", "B", "C"
), row.names = c(NA, -3L), class = "data.frame")

我现在想将这些字符转换为数字甚至是整数。但是,句点( . )不是十进制符号而是“千分位分隔符”(德语)。

我应该如何正确地转换数据框?

我尝试了这个:

df2 <- as.data.frame(apply(df1, 2, gsub, pattern = "([0-9])\\.([0-9])", replacement= "\\1\\2"))

df3 <- as.data.frame(data.matrix(df2))

然而,apply似乎会将每列转换为因子列表。我是否可以防止apply这样做?

如果问题在于值包含货币,那么该问题也已经在使用read.*函数的数据输入级别得到解决:http://stackoverflow.com/questions/10823241/how-can-i-completely-remove-scientific-notation-for-the-entire-r-session/10823641#10823641 - IRTFM
看了这些问题的答案和这里提供的解决方案(我会接受其中一个 - 我使用了我自己发布的那个,但@juba的解决方案似乎也可以),我认为这不是重复的... - speendo
需要解决的问题不是他的答案是否重复,而是问题是否重复。在发布问题之前,您应该进行更多的搜索。 - IRTFM
在发布之前,我发现了https://dev59.com/MXE95IYBdhLWcg3wWMlQ:OP想要删除逗号,而我想要删除点,我也无法将此线程中的答案翻译为我的问题。我之前没有找到http://stackoverflow.com/questions/10823241/how-can-i-completely-remove-scientific-notation-for-the-entire-r-session/10823641#10823641,但这解决了一个完全不同的问题。我在发布之前进行了大量搜索(信不信由你)。 - speendo
2个回答

9
您可以使用这个:
sapply(df, function(v) {as.numeric(gsub("\\.","", as.character(v)))})

这将会给予:

        A       B    C
[1,] 1100    7800  200
[2,] 2300     500 3100
[3,] 5400 1000000 4500

这将会给你一个“matrix”对象,但如果你愿意,可以将其包装到“data.frame()”中。
请注意,原始数据中的列不是字符而是因子。
编辑:或者,你可以使用以下方法直接将结果作为“data.frame”获取,而不是将其包装在“data.frame()”中:
# the as.character(.) is just in case it's loaded as a factor
df[] <- lapply(df, function(x) as.numeric(gsub("\\.", "", as.character(x))))

哦,你说得对 - 这个最小示例不好。在“真实”的数据中,它们是字符。 - speendo

2

我认为我找到了另一种解决方案:

使用stringsAsFactors = FALSE是必要的。

像这样:

df2 <- as.data.frame(apply(df1, 2, gsub, pattern = "([0-9])\\.([0-9])", replacement= "\\1\\2"), stringsAsFactors = FALSE)

df3 <- as.data.frame(data.matrix(df2))

我猜这只是替换两个点吧? - Arun
你为什么认为只有两个点?刚刚尝试了一下 structure(list(A = c("800.000.000.000", "2.034.312.421", "321.325.123.234" ), B = c("800.000.000.000", "2.034.312.421", "321.325.123.234" ), C = c("800.000.000.000", "2.034.312.421", "321.325.123.234" )), .Names = c("A", "B", "C"), row.names = c(NA, -3L), class = "data.frame") - 所有的点都被替换了。 - speendo
我认为这应该也可以工作。原则上,这个命令对数据框中的每个x运行gsub("([0-9])\\.([0-9])", "\\1\\2", x)。换句话说,该函数搜索所有模式<digit1>.<digit2>并将其替换为<digit1><digit2>。这应该适用于所有数字 - 但是在像<digit1>.<digit2>.<digit3>这样的模式中可能会出现问题,但是在这种情况下,点不会是千位分隔符。 - speendo
1
可能是因为个人联合的原因;-) - speendo
哈哈哈...刚注意到了!!我的天啊!我需要小睡一会儿!!!啊哈哈哈,这太搞笑了! - Arun
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接