Câu trả lời:
Vì (vẫn) không ai có dấu kiểm, tôi cho rằng bạn có một số vấn đề thực tế trong đầu, chủ yếu là do bạn chưa chỉ định loại vectơ nào bạn muốn chuyển đổi sang numeric
. Tôi đề nghị bạn nên áp dụng transform
chức năng để hoàn thành nhiệm vụ của mình.
Bây giờ tôi sắp chứng minh một số "dị thường chuyển đổi" nhất định:
# 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)
Chúng ta hãy lướt qua 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
và cho chúng tôi chạy:
> 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"
Bây giờ bạn có thể tự hỏi mình "dị thường ở đâu?" Chà, tôi đã va vào những thứ khá kỳ dị ở R, và đây không phải là điều khó hiểu nhất, nhưng nó có thể làm bạn bối rối, đặc biệt nếu bạn đọc điều này trước khi lăn vào giường.
Ở đây đi: hai cột đầu tiên là character
. Tôi đã cố tình gọi là 2 thứ một fake_char
. Phát hiện sự giống nhau của character
biến này với biến mà Dirk đã tạo trong câu trả lời của mình. Nó thực sự là một numerical
vector chuyển đổi thành character
. 3 thứ 4 thứ cột là factor
, và người cuối cùng là "thuần túy" numeric
.
Nếu bạn sử dụng transform
hàm, bạn có thể chuyển đổi fake_char
thành numeric
, nhưng không phải là char
biến.
> 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
nhưng nếu bạn làm điều tương tự fake_char
và char_fac
, bạn sẽ may mắn và thoát khỏi tình trạng không có 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
Nếu bạn lưu chuyển đổi data.frame
và kiểm tra mode
và class
, bạn sẽ nhận được:
> 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"
Vì vậy, kết luận là: Có, bạn có thể chuyển đổi character
vectơ thành một numeric
, nhưng chỉ khi các phần tử của nó là "có thể chuyển đổi" thành numeric
. Nếu chỉ có một character
phần tử trong vectơ, bạn sẽ gặp lỗi khi cố gắng chuyển đổi vectơ đó thành numerical
một phần tử.
Và chỉ để chứng minh quan điểm của tôi:
> 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
Và bây giờ, chỉ để giải trí (hoặc thực hành), hãy thử đoán đầu ra của các lệnh này:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Trân trọng kính chào Patrick Burns! =)
Một cái gì đó đã giúp tôi: nếu bạn có một loạt các biến để chuyển đổi (hoặc chỉ nhiều hơn một biến), bạn có thể sử dụng sapply
.
Một chút vô nghĩa nhưng chỉ là ví dụ:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Giả sử các cột 3, 6-15 và 37 của khung dữ liệu của bạn cần được chuyển đổi thành số một có thể:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapply
cuộc gọi ở as.data.frame()
phía bên tay phải, như @Mehrad Mahmoudian đề xuất bên dưới, nó sẽ hoạt động.
if x
là tên cột của dataframe dat
và x
là kiểu hệ số, hãy sử dụng:
as.numeric(as.character(dat$x))
as.character
thực sự là những gì tôi đang tìm kiếm. Nếu không, việc chuyển đổi đôi khi gặp trục trặc. Ít nhất là trong trường hợp của tôi.
Error: (list) object cannot be coerced to type 'double'
mặc dù tôi khá chắc chắn rằng vectơ của tôi không có ký tự / dấu chấm câu. Sau đó tôi đã thử as.numeric(as.character(dat$x))
và nó đã làm việc. Bây giờ tôi không chắc liệu cột của tôi trên thực tế chỉ có số nguyên hay không!
Mặc dù câu hỏi của bạn hoàn toàn đúng về số, có nhiều chuyển đổi rất khó hiểu khi bắt đầu R. Tôi sẽ nhắm đến các phương pháp để giải quyết. Câu hỏi này tương tự như Câu hỏi này .
Chuyển đổi loại có thể gây khó khăn cho R vì (1) các yếu tố không thể được chuyển đổi trực tiếp thành số, chúng cần được chuyển đổi thành lớp ký tự trước, (2) ngày là trường hợp đặc biệt mà bạn thường cần phải xử lý riêng và (3) lặp qua các cột khung dữ liệu có thể khó khăn. May mắn thay, "tidyverse" đã giải quyết hầu hết các vấn đề.
Giải pháp này sử dụng mutate_each()
để áp dụng một hàm cho tất cả các cột trong khung dữ liệu. Trong trường hợp này, chúng tôi muốn áp dụng type.convert()
hàm, chuyển đổi chuỗi thành số ở nơi có thể. Bởi vì R yêu thích các yếu tố (không chắc tại sao) các cột ký tự nên giữ nguyên ký tự được thay đổi thành yếu tố. Để khắc phục điều này, mutate_if()
chức năng được sử dụng để phát hiện các cột là các yếu tố và thay đổi thành ký tự. Cuối cùng, tôi muốn chỉ ra làm thế nào có thể sử dụng Lubridate để thay đổi dấu thời gian trong lớp nhân vật thành thời gian vì đây cũng thường là một khối gắn bó cho người mới bắt đầu.
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)
thay vì mutate_all(type.convert)
, bạn có thể xóa / tránh mutate_if(is.factor, as.character)
để rút ngắn lệnh. as.is
là một đối số trong type.convert()
đó cho biết liệu nó nên chuyển đổi chuỗi dưới dạng ký tự hay dưới dạng các yếu tố. Theo mặc định, as.is=FALSE
trong type.convert()
(nghĩa là chuyển đổi chuỗi thành lớp nhân tố thay vì lớp ký tự).
Tim là chính xác, và Shane có một thiếu sót. Dưới đây là các ví dụ bổ sung:
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
Bây giờ chúng ta có một bản tóm tắt về cột yếu tố (tổng số) và tóm tắt số của as.numeric()
--- sai vì nó có các mức yếu tố số --- và tóm tắt (chính xác) của as.numeric(as.character())
.
Với đoạn mã sau, bạn có thể chuyển đổi tất cả các cột của khung dữ liệu thành số (X là khung dữ liệu mà chúng tôi muốn chuyển đổi các cột của nó):
as.data.frame(lapply(X, as.numeric))
và để chuyển đổi toàn bộ ma trận thành số, bạn có hai cách: Hoặc:
mode(X) <- "numeric"
hoặc là:
X <- apply(X, 2, as.numeric)
Ngoài ra, bạn có thể sử dụng data.matrix
chức năng để chuyển đổi mọi thứ thành số, mặc dù lưu ý rằng các yếu tố có thể không được chuyển đổi chính xác, vì vậy sẽ an toàn hơn khi chuyển đổi mọi thứ thành character
đầu tiên:
X <- sapply(X, as.character)
X <- data.matrix(X)
Tôi thường sử dụng cái cuối cùng này nếu tôi muốn chuyển đổi thành ma trận và số đồng thời
Nếu bạn gặp vấn đề với:
as.numeric(as.character(dat$x))
Hãy nhìn vào dấu thập phân của bạn. Nếu chúng là "," thay vì "." (ví dụ "5,3") ở trên sẽ không hoạt động.
Một giải pháp tiềm năng là:
as.numeric(gsub(",", ".", dat$x))
Tôi tin rằng điều này khá phổ biến ở một số quốc gia không nói tiếng Anh.
Cách phổ quát sử dụng type.convert()
và 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
nếu bạn muốn chuyển đổi nhân vật của mình thành số hoặc yếu tố
matrix
thay đổi thành classes=matrix
số bị lỗi trong đối số đầu tiên phải có ký tự chế độ
Để chuyển đổi cột khung dữ liệu thành số, bạn chỉ cần thực hiện: -
hệ số thành số: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Mặc dù những người khác đã đề cập đến chủ đề này khá tốt, tôi muốn thêm ý nghĩ / gợi ý nhanh này. Bạn có thể sử dụng biểu thức chính quy để kiểm tra trước xem các ký tự có khả năng chỉ bao gồm số hay không.
for(i in seq_along(names(df)){
potential_numcol[i] <- all(!grepl("[a-zA-Z]",d[,i]))
}
# and now just convert only the numeric ones
d <- sapply(d[,potential_numcol],as.numeric)
Để biết các biểu thức chính quy tinh vi hơn và gọn gàng tại sao để tìm hiểu / trải nghiệm sức mạnh của họ, hãy xem trang web thực sự tốt đẹp này: http://regexr.com/
Xem xét có thể tồn tại các cột char, điều này dựa trên @Abdou trong Lấy các loại cột của bảng excel tự động trả lời:
makenumcols<-function(df){
df<-as.data.frame(df)
df[] <- lapply(df, as.character)
cond <- apply(df, 2, function(x) {
x <- x[!is.na(x)]
all(suppressWarnings(!is.na(as.numeric(x))))
})
numeric_cols <- names(df)[cond]
df[,numeric_cols] <- sapply(df[,numeric_cols], as.numeric)
return(df)
}
df<-makenumcols(df)
Nếu khung dữ liệu có nhiều loại cột, một số ký tự, một số số hãy thử cách sau để chuyển đổi chỉ các cột có chứa giá trị số thành số:
for (i in 1:length(data[1,])){
if(length(as.numeric(data[,i][!is.na(data[,i])])[!is.na(as.numeric(data[,i][!is.na(data[,i])]))])==0){}
else {
data[,i]<-as.numeric(data[,i])
}
}
với hablar :: convert
Để dễ dàng chuyển đổi nhiều cột thành các loại dữ liệu khác nhau, bạn có thể sử dụng hablar::convert
. Cú pháp đơn giản: df %>% convert(num(a))
chuyển đổi cột a từ df sang số.
Ví dụ chi tiết
Cho phép chuyển đổi tất cả các cột của mtcars
nhân vật.
df <- mtcars %>% mutate_all(as.character) %>% as_tibble()
> df
# A tibble: 32 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 21 6 160 110 3.9 2.62 16.46 0 1 4 4
2 21 6 160 110 3.9 2.875 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
Với hablar::convert
:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
kết quả trong:
# A tibble: 32 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<chr> <int> <dbl> <dbl> <dbl> <dbl> <chr> <int> <chr> <fct> <chr>
1 21 6 160 110 3.9 2.62 16.46 0 1 4 4
2 21 6 160 110 3.9 2.88 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
4 21.4 6 258 110 3.08 3.22 19.44 1 0 3 1
Để chuyển đổi ký tự thành số, bạn phải chuyển đổi nó thành yếu tố bằng cách áp dụng
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Bạn phải tạo hai cột có cùng dữ liệu, vì một cột không thể chuyển đổi thành số. Nếu bạn thực hiện một chuyển đổi, nó sẽ báo lỗi dưới đây
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
vì vậy, sau khi thực hiện hai cột của cùng một dữ liệu
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
nó sẽ biến đổi ký tự thành số thành công
df
ist dataframe của bạn. x
là một cột df
bạn muốn chuyển đổi
as.numeric(factor(df$x))
Nếu bạn không quan tâm đến việc bảo tồn các yếu tố và muốn áp dụng nó cho bất kỳ cột nào có thể được chuyển đổi thành số, tôi đã sử dụng tập lệnh bên dưới. nếu df là khung dữ liệu gốc của bạn, bạn có thể sử dụng tập lệnh bên dưới.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))