R data.frame 将字符转换为数字时的奇怪行为

R data.frame strange behavior when converting characters to numeric

我正在处理一个数据集,其中包含编码为字符的美国各州 FIPS 代码,其中从 1 到 9 的代码有时有一个 0 前缀(01、02,...)。在尝试清理它时,我遇到了以下问题:

test <- data.frame(fips = c(1,"01")) %>%
mutate(fips = as.numeric(fips))

> test
  fips
1    2
2    1

其中 1 被转换为 2,而 01 被转换为 1。这种烦人的行为随着小提示消失了:

test <- tibble(fips = c(1,"01")) %>%
        mutate(fips = as.numeric(fips))
> test
# A tibble: 2 x 1
   fips
  <dbl>
1     1
2     1

有人知道这是怎么回事吗? 谢谢

这是 tibbles 和 data.frames 默认值的区别。当您像 c(1, "01") 中那样将字符串和数字混合在一起时,R 会将所有内容都转换为字符串。

c(1, "01")
[1] "1"  "01"

data.frame 的默认行为是将字符串转换为因子。如果您查看 data.frame 的帮助页面,您将看到参数:

stringsAsFactors: ... The ‘factory-fresh’ default is TRUE

因此数据框使 c(1, "01") 成为具有两个级别 "1" 和 "01" 的因子

T1 = data.frame(fips = c(1,"01")) 
str(T1)
'data.frame':   2 obs. of  1 variable:
 $ fips: Factor w/ 2 levels "01","1": 2 1

现在因子以整数形式存储以提高效率。这就是为什么您在 str(T1) 的 about 输出末尾看到 2 1 的原因。因此,如果您直接将其转换为整数,则会得到 2 和 1。

您可以通过使用

更仔细地 data.frame 来获得您想要的行为
T1 = data.frame(fips = c(1,"01"), stringsAsFactors=FALSE)

您可以先将因子转换为字符串,然后再转换为数字

fips = as.numeric(as.character(fips))

Tibbles 没有这个问题,因为它们不会将字符串转换为因子。