我在R中工作,并且有一个带有数字向量的数据帧dd_2006。当我第一次导入数据时,我需要从3个变量中删除$,小数点和一些空格:SumOfCost,SumOfCases和SumOfUnits。为此,我使用了str_replace_all
。但是,一旦我使用str_replace_all
,矢量就会转换为字符。所以我使用as.numeric(var)将向量转换为数字,但引入了NAs,即使我在运行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中碰到了非常特殊的东西,这不是最令人困惑的东西,但它会让你感到困惑,特别是如果你在睡觉之前读到它。
这里说:前两列是字符。我故意称第二个为fake_char。发现这个角色变量与Dirk在回复中创建的变量的相似性。它实际上是一个转换为字符的数字向量。第3列和第4列是因子,最后一列是“纯粹”数字。
如果你使用转换函数,你可以将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)
等来查看观察结果,看看是否有任何我在观察中遗漏的角色,但没有任何角色。有关为什么会出现这些新闻的想法,以及如何摆脱它们?
答案 0 :(得分:13)
正如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消失为止。
更新:看起来问题出在您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
除非这为您实现某些特定目的,否则我建议完全从预处理中删除此步骤,因为它似乎没有必要,似乎给您带来了问题。
答案 1 :(得分:4)
如果要将字符转换为数字,则首先将其转换为因子(使用as.factor)并保存/覆盖现有变量。接下来将此因子变量转换为数字(使用as.numeric)。您不会以这种方式创建NA,并且能够将您拥有的数据集转换为数字。
答案 2 :(得分:0)
一种简单的解决方案是让retype
猜测每一列的新数据类型
library(dplyr)
library(hablar)
dd_2006 %>% retype()