r - 在R中不使用NA强制将字符转换为数值

标签 r vector character numeric na

我正在R中工作,并且有一个数据框dd_2006,带有数值向量。首次导入数据时,需要从3个变量中删除$,小数点和一些空格:SumOfCost,SumOfCases和SumOfUnits。为此,我使用了str_replace_all。但是,一旦我使用了str_replace_all,矢量便被转换为字符。因此,我使用as.numeric(var)将向量转换为数字,但是引入了NA,即使我在运行as.numeric代码之前运行下面的代码时,向量中也没有NA。

sum(is.na(dd_2006$SumOfCost))
[1] 0
sum(is.na(dd_2006$SumOfCases))
[1] 0
sum(is.na(dd_2006$SumOfUnits))
[1] 0

这是我导入后的代码,首先是从向量中删除$。在str(dd_2006)输出中,为了节省空间,我删除了一些变量,因此下面的str_replace_all代码中的#s列与我在此处发布的输出不匹配(但在原始代码中确实如此):
library("stringr")
dd_2006$SumOfCost <- str_sub(dd_2006$SumOfCost, 2, ) #2=the first # after the $

#Removes decimal pt, zero's after, and commas
dd_2006[ ,9] <- str_replace_all(dd_2006[ ,9], ".00", "")
dd_2006[,9] <- str_replace_all(dd_2006[,9], ",", "")

dd_2006[ ,10] <- str_replace_all(dd_2006[ ,10], ".00", "")
dd_2006[ ,10] <- str_replace_all(dd_2006[,10], ",", "")

dd_2006[ ,11] <- str_replace_all(dd_2006[ ,11], ".00", "")
dd_2006[,11] <- str_replace_all(dd_2006[,11], ",", "")

str(dd_2006)
'data.frame':   12604 obs. of  14 variables:
 $ CMHSP                     : Factor w/ 46 levels "Allegan","AuSable Valley",..: 1 1 1
 $ FY                        : Factor w/ 1 level "2006": 1 1 1 1 1 1 1 1 1 1 ...
 $ Population                : Factor w/ 1 level "DD": 1 1 1 1 1 1 1 1 1 1 ...
 $ SumOfCases                : chr  "0" "1" "0" "0" ...
 $ SumOfUnits                : chr  "0" "365" "0" "0" ...
 $ SumOfCost                 : chr  "0" "96416" "0" "0" ...

我使用以下代码找到了与here类似的问题的响应:
# create dummy data.frame
d <- data.frame(char = letters[1:5], 
                fake_char = as.character(1:5), 
                fac = factor(1:5), 
                char_fac = factor(letters[1:5]), 
                num = 1:5, stringsAsFactors = FALSE)

让我们看一下data.frame
> d
  char fake_char fac char_fac num
1    a         1   1        a   1
2    b         2   2        b   2
3    c         3   3        c   3
4    d         4   4        d   4
5    e         5   5        e   5

让我们运行:
> sapply(d, mode)
       char   fake_char         fac    char_fac         num 
"character" "character"   "numeric"   "numeric"   "numeric" 
> sapply(d, class)
       char   fake_char         fac    char_fac         num 
"character" "character"    "factor"    "factor"   "integer" 

现在您可能会问自己:“哪里有异常?”好吧,我碰到了R中非常奇怪的东西,这不是最令人困惑的事情,但是它会使您感到困惑,特别是如果您在上床 sleep 之前读了这本书的话。

往前走:前两列是字符。我故意叫第二个fake_char。找出该字符变量与Dirk在他的回复中创建的变量的相似性。它实际上是一个转换为字符的数字矢量。第三列和第四列是因子,最后一列是“纯”数字。

如果您使用转换功能,则可以将fake_char转换为数字,但不能转换为char变量本身。
> transform(d, char = as.numeric(char))
  char fake_char fac char_fac num
1   NA         1   1        a   1
2   NA         2   2        b   2
3   NA         3   3        c   3
4   NA         4   4        d   4
5   NA         5   5        e   5
Warning message:
In eval(expr, envir, enclos) : NAs introduced by coercion
but if you do same thing on fake_char and char_fac, you'll be lucky, and get away with no NA's:

transform(d, fake_char = as.numeric(fake_char), char_fac = as.numeric(char_fac))


  char fake_char fac char_fac num
1    a         1   1        1   1
2    b         2   2        2   2
3    c         3   3        3   3
4    d         4   4        4   4
5    e         5   5        5   5

因此,我在脚本中尝试了上述代码,但仍然提出了NA(没有有关强制的警告消息)。
#changing sumofcases, cost, and units to numeric
dd_2006_1 <- transform(dd_2006, SumOfCases = as.numeric(SumOfCases), SumOfUnits = as.numeric(SumOfUnits), SumOfCost = as.numeric(SumOfCost))

> sum(is.na(dd_2006_1$SumOfCost))
[1] 12
> sum(is.na(dd_2006_1$SumOfCases))
[1] 7
> sum(is.na(dd_2006_1$SumOfUnits))
[1] 11

我还使用了table(dd_2006$SumOfCases)等来查看观察结果,以查看观察结果中是否缺少任何字符,但是没有。关于为什么会出现NA的任何想法,以及如何摆脱它们?

最佳答案

正如Anando指出的那样,问题出在您的数据中,如果没有可复制的示例,我们将无法真正为您提供帮助。也就是说,这是一个代码段,可帮助您确定导致问题的数据中的记录:

test = as.character(c(1,2,3,4,'M'))
v = as.numeric(test) # NAs intorduced by coercion
ix.na = is.na(v)
which(ix.na) # row index of our problem = 5
test[ix.na]  # shows the problematic record, "M"

不必猜测为什么要引入NA,而要取出引起问题的记录并直接/单独解决它们,直到NA消失为止。

更新:看起来问题出在您对str_replace_all的调用中。我不知道stringr库,但我认为您可以使用gsub完成相同的操作,如下所示:
v2 = c("1.00","2.00","3.00")
gsub("\\.00", "", v2)

[1] "1" "2" "3"

我不完全确定这会完成什么:
sum(as.numeric(v2)!=as.numeric(gsub("\\.00", "", v2))) # Illustrate that vectors are equivalent.

[1] 0

除非这可以为您实现某些特定目的,否则建议您完全放弃此步骤,因为这似乎没有必要,而且似乎给您带来了问题。

关于r - 在R中不使用NA强制将字符转换为数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17598020/

相关文章:

c++ - 迭代器类型中使用的 vector 元素类型

c++ - 将大量数字 vector 保存到硬盘驱动器

Excel:如果单元格有空格,则在第一个空格之前提取单元格中的字符

c - 在 C 中打印希腊字符

html - 增加整个 HTML Rmarkdown 输出的宽度

r - 更改 jupyter notebook 警告语言

r - 在 spatstat 中使用 sf 多边形对象作为窗口

oracle - 如何让 OCI 库在带有 R Oracle 的红帽机器上工作?

haskell - 为什么盒装向量这么慢?

c# - 字符串中不需要的转义字符