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ć transformfunkcję 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 characterzmiennej do zmiennej, którą Dirk stworzył w swojej odpowiedzi. W rzeczywistości jest to numericalwektor przekonwertowany na character. 3 III i 4 p kolumny są factor, a ostatni jest „wyłącznie” numeric.
Jeśli korzystasz z transformfunkcji, możesz przekonwertować zmienną fake_charna numeric, ale nie charsamą 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_chari char_facbę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.framei sprawdzisz modei 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ć characterwektor na numericjeden, ale tylko wtedy, gdy jego elementy są „konwertowalne” na numeric. Jeśli characterw wektorze jest tylko jeden element, podczas próby konwersji tego wektora na numericaljeden 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)
sapplypołączenie as.data.frame()po prawej stronie, jak sugerował poniżej @Mehrad Mahmoudian, zadziała.
jeśli xjest nazwą kolumny ramki danych dati xjest typu, użyj:
as.numeric(as.character(dat$x))
as.characterrzeczywiś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.isjest argumentem type.convert()wskazującym, czy powinien konwertować ciągi znaków jako znaki, czy jako czynniki. Domyślnie as.is=FALSEin 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.frameteraz 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.matrixfunkcji, aby przekonwertować wszystko na wartości liczbowe, chociaż pamiętaj, że czynniki mogą nie zostać poprawnie przekonwertowane, więc bezpieczniej jest przekonwertować wszystko na characternajpierw:
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 = TRUEjeśli chcesz przekonwertować swoją postać na
matrixna zmiany numeryczne, zignorowany classes=matrixpierwszy 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 mtcarsna 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
dfistnieje twoja ramka danych. xto kolumna, dfktó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)))