Odpowiedzi:
Ponieważ (wciąż) nikt nie dostał znacznika wyboru, zakładam, że masz na myśli jakiś praktyczny problem, głównie dlatego, że nie określiłeś, jakiego rodzaju wektora chcesz przekonwertować numeric
. Proponuję zastosować transform
funkcję w celu wykonania zadania.
Teraz zamierzam zademonstrować pewną „anomalię konwersji”:
# 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)
Rzućmy okiem na 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
i pozwól nam uruchomić:
> 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"
Teraz prawdopodobnie zadajesz sobie pytanie „Gdzie jest anomalia?” Cóż, natknąłem się na dość osobliwe rzeczy w R i nie jest to najbardziej kłopotliwa sprawa, ale może cię to dezorientować, szczególnie jeśli przeczytasz to przed zjechaniem do łóżka.
Oto dwie pierwsze kolumny character
. Ja celowo nazywane 2 nd jeden fake_char
. Dostrzeż podobieństwo tej character
zmiennej do zmiennej, którą Dirk stworzył w swojej odpowiedzi. W rzeczywistości jest to numerical
wektor przekonwertowany na character
. 3 III i 4 p kolumny są factor
, a ostatni jest „wyłącznie” numeric
.
Jeśli korzystasz z transform
funkcji, możesz przekonwertować zmienną fake_char
na numeric
, ale nie char
samą zmienną.
> 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
ale jeśli zrobisz to samo na, fake_char
i char_fac
będziesz miał szczęście i nie będziesz mieć żadnych 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
Jeśli zapiszesz przekształcone data.frame
i sprawdzisz mode
i class
, otrzymasz:
> 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"
Wniosek jest następujący: Tak, możesz przekonwertować character
wektor na numeric
jeden, ale tylko wtedy, gdy jego elementy są „konwertowalne” na numeric
. Jeśli character
w wektorze jest tylko jeden element, podczas próby konwersji tego wektora na numerical
jeden wystąpi błąd .
I tylko, aby udowodnić mój punkt widzenia:
> 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
A teraz, dla zabawy (lub ćwiczenia), spróbuj odgadnąć wyjście tych poleceń:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Pozdrawiam Patrick Burns! =)
Coś, co mi pomogło: jeśli masz zakresy zmiennych do konwersji (lub tylko więcej niż jeden), możesz użyć sapply
.
Trochę bezsensowne, ale tylko na przykład:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Powiedzmy, że kolumny 3, 6-15 i 37 twojej ramki danych muszą zostać przekonwertowane na numeryczne, że można:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapply
połączenie as.data.frame()
po prawej stronie, jak sugerował poniżej @Mehrad Mahmoudian, zadziała.
jeśli x
jest nazwą kolumny ramki danych dat
i x
jest typu, użyj:
as.numeric(as.character(dat$x))
as.character
rzeczywiście było tym, czego szukałem. W przeciwnym razie konwersja czasami się nie powiedzie. Przynajmniej w moim przypadku.
Error: (list) object cannot be coerced to type 'double'
chociaż byłem dość pewien, że mój wektor nie ma znaków / znaków interpunkcyjnych. Potem spróbowałem as.numeric(as.character(dat$x))
i zadziałało. Teraz nie jestem pewien, czy moja kolumna jest w rzeczywistości tylko liczbami całkowitymi, czy nie!
Chociaż twoje pytanie dotyczy wyłącznie liczb, istnieje wiele konwersji, które trudno zrozumieć na początku R. Postaram się zająć metodami, które pomogą. To pytanie jest podobne do tego pytania .
Konwersja typów może być uciążliwa w R, ponieważ (1) czynników nie można bezpośrednio przekonwertować na wartości liczbowe, najpierw należy je przekonwertować na klasę znaków, (2) daty są szczególnym przypadkiem, z którym zwykle trzeba sobie poradzić osobno, i (3) zapętlanie kolumn kolumn danych może być trudne. Na szczęście „tidyverse” rozwiązało większość problemów.
W tym rozwiązaniu mutate_each()
zastosowano funkcję do wszystkich kolumn w ramce danych. W tym przypadku chcemy zastosować type.convert()
funkcję, która konwertuje ciągi znaków na wartości liczbowe tam, gdzie to możliwe. Ponieważ R uwielbia czynniki (nie wiem dlaczego) kolumny znaków, które powinny pozostać, zostaną zmienione na czynniki. Aby to naprawić, mutate_if()
funkcja służy do wykrywania kolumn, które są czynnikami i zmieniają się w znak. Na koniec chciałem pokazać, jak można użyć lubridate, aby zmienić znacznik czasu w klasie postaci na datę i godzinę, ponieważ jest to często blokada dla początkujących.
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)
zamiast mutate_all(type.convert)
, możesz usunąć / uniknąć, mutate_if(is.factor, as.character)
aby skrócić polecenie. as.is
jest argumentem type.convert()
wskazującym, czy powinien konwertować ciągi znaków jako znaki, czy jako czynniki. Domyślnie as.is=FALSE
in type.convert()
(tzn. Konwertuje ciągi znaków na klasę współczynnika zamiast na klasę znaków).
Tim ma rację, a Shane ma pominięcie. Oto dodatkowe przykłady:
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>
Nasz data.frame
teraz ma podsumowanie kolumny czynników (liczby) i podsumowania liczbowe as.numeric()
--- co jest nieprawidłowe, ponieważ ma poziomy liczbowe współczynników --- oraz (poprawne) podsumowanie as.numeric(as.character())
.
Za pomocą następującego kodu możesz przekonwertować wszystkie kolumny ramek danych na wartości liczbowe (X to ramka danych, którą chcemy przekonwertować to kolumny):
as.data.frame(lapply(X, as.numeric))
a do konwersji całej macierzy na wartości liczbowe masz dwa sposoby: albo:
mode(X) <- "numeric"
lub:
X <- apply(X, 2, as.numeric)
Alternatywnie możesz użyć data.matrix
funkcji, aby przekonwertować wszystko na wartości liczbowe, chociaż pamiętaj, że czynniki mogą nie zostać poprawnie przekonwertowane, więc bezpieczniej jest przekonwertować wszystko na character
najpierw:
X <- sapply(X, as.character)
X <- data.matrix(X)
Zazwyczaj używam tego ostatniego, jeśli chcę jednocześnie przekonwertować na macierz i cyfrę
Jeśli wystąpią problemy z:
as.numeric(as.character(dat$x))
Spójrz na swoje znaki dziesiętne. Jeśli są „,” zamiast „.” (np. „5,3”) powyższe nie będzie działać.
Potencjalnym rozwiązaniem jest:
as.numeric(gsub(",", ".", dat$x))
Uważam, że jest to dość powszechne w niektórych krajach nieanglojęzycznych.
Uniwersalny sposób za pomocą type.convert()
i 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
jeśli chcesz przekonwertować swoją postać na
matrix
na zmiany numeryczne, zignorowany classes=matrix
pierwszy argument musi mieć postać trybu
Aby przekonwertować kolumnę ramki danych na numeryczną, wystarczy:
współczynnik na wartość liczbową: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Chociaż inni dość dobrze omawiali ten temat, chciałbym dodać tę dodatkową szybką myśl / wskazówkę. Możesz użyć wyrażenia regularnego, aby z góry sprawdzić, czy znaki potencjalnie składają się tylko z cyfr.
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)
Bardziej wyrafinowane wyrażenia regularne i ciekawe, dlaczego warto uczyć się / doświadczać ich mocy, zobacz tę naprawdę fajną stronę internetową: http://regexr.com/
Biorąc pod uwagę, że mogą istnieć kolumny char, jest to oparte na @Abdou w Uzyskaj typy kolumn arkusza programu Excel automatycznie odpowiedz:
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)
Jeśli ramka danych ma wiele typów kolumn, niektóre znaki, niektóre wartości liczbowe, spróbuj wykonać następujące czynności, aby przekonwertować tylko kolumny zawierające wartości liczbowe na wartości liczbowe:
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])
}
}
z hablar :: konwersją
Aby łatwo przekonwertować wiele kolumn na różne typy danych, których możesz użyć hablar::convert
. Prosta składnia: df %>% convert(num(a))
konwertuje kolumnę a z df na numeryczną.
Szczegółowy przykład
Pozwala przekonwertować wszystkie kolumny mtcars
na znak.
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
Z hablar::convert
:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
prowadzi do:
# 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
Aby przekonwertować znak na numeryczny, musisz go przekonwertować na współczynnik, stosując
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Musisz utworzyć dwie kolumny z tymi samymi danymi, ponieważ jedna kolumna nie może zostać przekonwertowana na liczbę. Jeśli wykonasz jedną konwersję, pojawi się poniższy błąd
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
więc po wykonaniu dwóch kolumn tych samych danych stosuje się
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
z powodzeniem przekształci znak w numeryczny
df
istnieje twoja ramka danych. x
to kolumna, df
którą chcesz przekonwertować
as.numeric(factor(df$x))
Jeśli nie zależy ci na zachowaniu czynników i chcesz zastosować je do dowolnej kolumny, którą można przekonwertować na wartości liczbowe, skorzystałem ze skryptu poniżej. jeśli df jest twoją oryginalną ramką danych, możesz użyć skryptu poniżej.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))