如何将数据框的列转换为数字类型?
由于(仍然)没有人被勾选为最佳答案,我假设你有一些实际的问题需要解决,这很大程度上是因为你没有指定要转换为numeric
的向量类型。我建议你应该使用transform
函数来完成任务。
现在我将展示某种“转换异常”:
# 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中遇到了一些相当奇怪的事情,这并不是最令人困惑的事情,但它可能会让你感到困惑,特别是如果你在上床睡觉之前读了这个。
接下来:前两列是character
。我故意称第二列为fake_char
。注意这个character
变量与Dirk在他的回复中创建的变量的相似之处。它实际上是一个转换为character
的numerical
向量。第三和第四列是factor
,最后一列是"纯粹的"numeric
。
如果您使用transform
函数,可以将fake_char
转换为numeric
,但不能转换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
但如果你在fake_char
和char_fac
上做同样的事情,那么你会很幸运,没有出现NA值:
> 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
如果您保存了转换后的data.frame
并检查其mode
和class
,则会得到:
> D <- transform(d, fake_char = as.numeric(fake_char),
char_fac = as.numeric(char_fac))
> sapply(D, mode)
char fake_char fac char_fac num
"character" "numeric" "numeric" "numeric" "numeric"
> sapply(D, class)
char fake_char fac char_fac num
"character" "numeric" "factor" "numeric" "integer"
所以,结论是:是的,您可以将字符
向量转换为数字
向量,但前提是其元素“可转换”为数字
。 如果向量中只有一个字符
元素,则在尝试将该向量转换为数字
向量时会出现错误。> err <- c(1, "b", 3, 4, "e")
> mode(err)
[1] "character"
> class(err)
[1] "character"
> char <- as.numeric(err)
Warning message:
NAs introduced by coercion
> char
[1] 1 NA 3 4 NA
现在,只是为了好玩(或练习),试着猜一下这些命令的输出结果:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
向Patrick Burns致以亲切问候!=)
有一个帮助我的方法:如果你有多个要转换的变量范围(或只是超过一个),你可以使用sapply
。
可能有点不太讲得通,但只是举个例子:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
假设你的数据框中的第3列、6-15列和37列需要转换为数值类型,可以采取以下方法:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapply
调用包装在as.data.frame()
中,就像@Mehrad Mahmoudian 在下面建议的那样,它就可以工作了。 - knowahx
是数据框dat
的列名,并且x
的类型为因子,使用以下代码:as.numeric(as.character(dat$x))
as.character
确实是我需要的。否则有时候转换会出错,至少在我的情况下是这样。 - Thieme HennisError: (list) object cannot be coerced to type 'double'
,尽管我相当确定我的向量没有字符/标点符号。然后我尝试了as.numeric(as.character(dat$x))
,它起作用了。现在我不确定我的列是否只包含整数! - vagabond我本想添加评论(但评分太低)
只是想补充一下用户276042和pangratz的意见。
dat$x = as.numeric(as.character(dat$x))
这将覆盖现有列x的值。
使用以下代码可以将数据框中的所有列转换为数字类型(X是需要转换其列的数据框):
as.data.frame(lapply(X, as.numeric))
将整个矩阵转换为数字的方法有两种:
要么:mode(X) <- "numeric"
X <- apply(X, 2, as.numeric)
或者您可以使用data.matrix
函数将所有内容转换为数字,但请注意因子可能无法正确转换,所以最安全的做法是先将所有内容转换为字符
:
X <- sapply(X, as.character)
X <- data.matrix(X)
如果我想同时将矩阵转换为数值,我通常使用最后一个选项。
mutate_each()
来为数据框中的所有列应用一个函数。在这种情况下,我们想应用type.convert()
函数,它将可转换为数值型的字符串转换为数值型。因为R喜欢因子(不确定为什么),所以本来应该保持为字符型的列会被更改为因子。为了解决这个问题,使用mutate_if()
函数检测是因子的列,并将其更改为字符型。最后,我想展示一下lubridate如何用于将字符型时间戳更改为日期时间,因为这也经常是初学者的难点。library(tidyverse)
library(lubridate)
# Recreate data that needs converted to numeric, date-time, etc
data_df
#> # A tibble: 5 × 9
#> TIMESTAMP SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
#> 2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
#> 3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
#> 4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
#> 5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
# Converting columns to numeric using "tidyverse"
data_df %>%
mutate_all(type.convert) %>%
mutate_if(is.factor, as.character) %>%
mutate(TIMESTAMP = as_datetime(TIMESTAMP, tz = Sys.timezone()))
#> # A tibble: 5 × 9
#> TIMESTAMP SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
#> <dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
#> 1 2012-05-04 09:30:00 BAC T 7.890 38538 F 7.89 523 7.90
#> 2 2012-05-04 09:30:01 BAC Z 7.885 288 @ 7.88 61033 7.90
#> 3 2012-05-04 09:30:03 BAC X 7.890 1000 @ 7.88 1974 7.89
#> 4 2012-05-04 09:30:07 BAC T 7.890 19052 F 7.88 1058 7.89
#> 5 2012-05-04 09:30:08 BAC Y 7.890 85053 F 7.88 108101 7.90
mutate_all(type.convert, as.is=TRUE)
而不是mutate_all(type.convert)
,则可以删除/避免mutate_if(is.factor, as.character)
以缩短命令。 as.is
是type.convert()
中的一个参数,指示它是否应将字符串转换为字符或因子。默认情况下,在type.convert()
中as.is=FALSE
(即将字符串转换为因子类而不是字符类)。 - LC-datascientistas.numeric(as.character(dat$x))
检查一下你的十进制符号。如果它们是“,”而不是“。”(例如,“5,3”),则上述方法将无法正常工作。
一个可能的解决方案是:
as.numeric(gsub(",", ".", dat$x))
我相信在一些非英语国家这是相当普遍的。
提姆是正确的,而谢恩有一个遗漏。这里有更多的例子:
R> df <- data.frame(a = as.character(10:15))
R> df <- data.frame(df, num = as.numeric(df$a),
numchr = as.numeric(as.character(df$a)))
R> df
a num numchr
1 10 1 10
2 11 2 11
3 12 3 12
4 13 4 13
5 14 5 14
6 15 6 15
R> summary(df)
a num numchr
10:1 Min. :1.00 Min. :10.0
11:1 1st Qu.:2.25 1st Qu.:11.2
12:1 Median :3.50 Median :12.5
13:1 Mean :3.50 Mean :12.5
14:1 3rd Qu.:4.75 3rd Qu.:13.8
15:1 Max. :6.00 Max. :15.0
R>
现在我们的data.frame
含有因子列的摘要(计数)和as.numeric()
函数生成的数字摘要 --- 由于它获取了数字因子水平,所以是错误的 --- 以及as.numeric(as.character())
的(正确的)摘要。
使用 type.convert()
和 rapply()
的通用方法:
convert_types <- function(x) {
stopifnot(is.list(x))
x[] <- rapply(x, utils::type.convert, classes = "character",
how = "replace", as.is = TRUE)
return(x)
}
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)
sapply(d, class)
#> char fake_char fac char_fac num
#> "character" "character" "factor" "factor" "integer"
sapply(convert_types(d), class)
#> char fake_char fac char_fac num
#> "character" "integer" "factor" "factor" "integer"
as.is = TRUE
即可。 - qfazillematrix
的数据框中的一列更改为数值类型时,会出现 classes=matrix
错误。第一个参数必须为字符模式。 - add-semi-colons因子转数字:
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
。 - data-frame-gg
transform
。 - jimh