【问题标题】:Remove thousand's separator [duplicate]删除千位分隔符[重复]
【发布时间】:2013-04-05 12:09:38
【问题描述】:

我导入了一个 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")

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

如何正确转换数据框?

我试过这个:

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.* 函数在数据输入级别解决:stackoverflow.com/questions/10823241/…
  • 查看这些问题的答案和此处提供的解决方案(我会接受其中一个 - 我使用了我自己发布的那个,但@juba 的解决方案似乎也有效),我认为它是不是重复的...
  • 要解决的问题是不是他的答案是否重复,而是问题是否重复。您应该在发布问题之前进行更多搜索。
  • 我在发帖前找到了stackoverflow.com/questions/2347410/…:OP想要删除一个逗号,我想删除一个dot,我也无法将此线程中的答案翻译成我的问题。我之前没有找到stackoverflow.com/questions/10823241/…,但这解决了一个完全不同的问题。我在发布之前做了很多搜索(信不信由你)。

标签: r excel decimal apply separator


【解决方案1】:

你可以用这个:

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))))

【讨论】:

  • 哦,你是对的 - 糟糕的最小示例。在“真实”数据中,它们是字符。
【解决方案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))

【讨论】:

  • 我猜这只会替换 2 个点?
  • 为什么你认为只有 2 个点?刚刚用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") 试了一下——所有的点都被替换了。
  • 是的,对不起,我不知道我为什么这么说。但是,如果数字是“.578”,这将不起作用,对吧?
  • 我认为它也应该可以工作。原则上,这会为数据框中的每个x 运行命令gsub("([0-9])\\.([0-9])", "\\1\\2", x)。换句话说,该函数搜索所有模式&lt;digit1&gt;.&lt;digit2&gt; 并将它们替换为&lt;digit1&gt;&lt;digit2&gt;。这应该适用于所有数字 - 像&lt;digit1&gt;.&lt;digit2&gt;.&lt;digit3&gt; 这样的模式可能会出现问题,但这里的点无论如何都不是千位分隔符。
  • 可能是因为个人结合 ;-)
猜你喜欢
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多