【问题标题】:How to convert entire dataframe to numeric while preserving decimals?如何在保留小数的同时将整个数据帧转换为数字?
【发布时间】:2014-12-11 02:00:05
【问题描述】:

我有一个混合类数据框(数字和因子),我试图将整个数据框转换为数字。下面说明了我正在使用的数据类型以及我遇到的问题:

> a = as.factor(c(0.01,0.02,0.03,0.04))
> b = c(2,4,5,7)
> df1 = data.frame(a,b)
> class(df1$a)
[1] "factor"
> class(df1$b)
[1] "numeric"

当我尝试将整个数据框转换为数值时,它会改变数值。例如:

> df2 = as.data.frame(sapply(df1, as.numeric))
> class(df2$a)
[1] "numeric"
> df2
  a b
1 1 2
2 2 4
3 3 5
4 4 7

此站点上的先前帖子建议使用as.numeric(as.character(df1$a)),它适用于一个专栏。但是,我需要将此方法应用于可能包含数百列的数据框。

我有哪些选项可以将整个数据帧从因子转换为数字,同时保留数字十进制值?

以下是我想要产生的输出,其中ab 是数字:

     a b
1 0.01 2
2 0.02 4
3 0.03 5
4 0.04 7

我已阅读以下相关帖子,但没有一篇直接适用于此案例:

  1. How to convert a factor variable to numeric while preserving the numbers in R 这引用了数据框中的单个列。
  2. converting from a character to a numeric data frame。这个帖子 不考虑十进制值。
  3. How can i convert a factor column that contains decimal numbers to numeric?。这仅适用于数据框中的一列。

【问题讨论】:

  • 提问的好方法。 This question 可能会有所帮助。这是对factor 变量感到沮丧的常见原因。

标签: r dataframe numeric


【解决方案1】:

您可能需要进行一些检查。您不能安全地将因子直接转换为数字。 as.character 必须先申请。否则,因子将被转换为其数值存储值。我会用is.factor 检查每一列,然后根据需要强制转换为数字。

df1[] <- lapply(df1, function(x) {
    if(is.factor(x)) as.numeric(as.character(x)) else x
})
sapply(df1, class)
#         a         b 
# "numeric" "numeric" 

【讨论】:

  • 或者在循环之外执行:is_factor &lt;- vapply(df1, is.factor, logical(1)); df1[is_factor] &lt;- ...
  • @hadley - 我一直在想这个。先检查,然后在子集上运行更改更有效?而不是检查 lapply 循环内部?
  • 考虑到典型数据集的大小,我怀疑它会产生很大的不同
【解决方案2】:

使用dplyr(有点像sapply..)

df2 <- mutate_all(df1, function(x) as.numeric(as.character(x)))

给出:

glimpse(df2)
Observations: 4
Variables: 2
$ a <dbl> 0.01, 0.02, 0.03, 0.04
$ b <dbl> 2, 4, 5, 7

来自您的 df1,它是:

glimpse(df1)
Observations: 4
Variables: 2
$ a <fctr> 0.01, 0.02, 0.03, 0.04
$ b <dbl> 2, 4, 5, 7

【讨论】:

    【解决方案3】:
    df2 <- data.frame(apply(df1, 2, function(x) as.numeric(as.character(x))))
    

    【讨论】:

      【解决方案4】:
      > df2 <- data.frame(sapply(df1, function(x) as.numeric(as.character(x))))
      > df2
           a b
      1 0.01 2
      2 0.02 4
      3 0.03 5
      4 0.04 7
      > sapply(df2, class)
              a         b 
      "numeric" "numeric" 
      

      【讨论】:

      • 我可能是错的,但这不会将数字列转换为字符然后再转换回数字吗?
      • @RichardScriven 认为这是对的。我认为我的回答遇到了同样的问题,尽管我认为这不是特别成问题。
      • @n8sty 不,一点问题都没有,但是好像有点浪费。
      猜你喜欢
      • 2020-12-06
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 2021-05-13
      • 2023-02-02
      • 2017-11-27
      相关资源
      最近更新 更多