Jak przekonwertować kolumnę ramki danych na typ numeryczny?
Jak przekonwertować kolumnę ramki danych na typ liczbowy?
18 answers
Ponieważ (nadal) nikt nie otrzymał znacznika wyboru, zakładam, że masz jakiś praktyczny problem na myśli, głównie dlatego, że nie określiłeś, jaki typ wektora chcesz przekonwertować na numeric
. Sugeruję, abyś zastosował transform
funkcję, aby wykonać swoje zadanie.
# 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 biegnijmy:
> 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 pewnie zadajesz sobie pytanie " gdzie jest anomalia?"Cóż, wpadłem na dość osobliwe rzeczy w R, i to nie jest najbardziej myląca rzecz, ale może cię zmylić, zwłaszcza jeśli przeczytasz to przed położeniem się do łóżka.
Zaczyna się: pierwsze dwie kolumny to character
. Celowo nazwałem 2 nd jeden fake_char
. Zauważ podobieństwo tej zmiennej character
do tej, którą Dirk stworzył w swojej odpowiedzi. Jest to wektor numerical
zamieniony na character
. 3rd i 4TH kolumny to factor
, a ostatni to "czysto" numeric
.
Jeśli użyjesz funkcji transform
, możesz przekonwertować fake_char
na numeric
, ale nie samą zmienną 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
Ale jeśli zrobisz to samo na fake_char
i char_fac
, będziesz miał szczęście i ujdzie ci to na sucho:
> 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 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"
Więc wniosek jest: tak, można przekonwertować character
wektor na numeric
jeden, ale tylko wtedy, gdy są to elementy są "convertible" do numeric
. jeśli jest tylko jeden character
element w wektorze, pojawi się błąd podczas próby przekonwertowania tego wektora na numerical
jeden.
I tylko dla udowodnienia mojej racji:
> 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 praktyki), spróbuj odgadnąć wynik tych poleceń:]}
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Pozdrawiam Patricka Burnsa! =)Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-19 00:31:30
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 ramki danych muszą być przekonwertowane na liczbowe:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-06 22:45:56
Jeśli x
jest nazwą kolumny ramki danych dat
, a x
jest czynnikiem typu, użyj:
as.numeric(as.character(dat$x))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-22 08:54:30
Dodałbym komentarz (cant niska ocena)
Wystarczy dodać na user276042 i pangratz
dat$x = as.numeric(as.character(dat$x))
To nadpisze wartości istniejącej kolumny x
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-06 05:58:06
Podczas gdy twoje pytanie jest ściśle numeryczne, istnieje wiele konwersji, które są trudne do zrozumienia podczas rozpoczynania R. postaram się zająć metodami, które pomogą. To pytanie jest podobne do tego pytania .
Konwersja typu może być uciążliwa w R, ponieważ (1) współczynniki nie mogą być przekonwertowane bezpośrednio na liczbę, muszą być najpierw przekonwertowane na klasę znaków, (2) daty są szczególnym przypadkiem, z którym zazwyczaj trzeba sobie poradzić osobno, oraz (3) zapętlanie kolumn ramki danych to może być trudne. Na szczęście "tidyverse" rozwiązał większość problemów.
To rozwiązanie wykorzystuje mutate_each()
do zastosowania funkcji do wszystkich kolumn w ramce danych. W tym przypadku chcemy zastosować funkcję type.convert()
, która zamienia ciągi znaków na liczbowe, gdzie może. Ponieważ r loves factors (Nie wiem dlaczego) kolumny znaków, które powinny pozostać znakami, zostają zmienione na factor. Aby to naprawić, funkcja mutate_if()
jest używana do wykrywania kolumn, które są czynnikami i zmiany na znak. Na koniec chciałem pokazać jak lubridate może być użyty do zmiany znacznika czasu w klasie character na date-time, ponieważ często jest to blok 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-24 23:45:07
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
ma teraz podsumowanie kolumny czynnika (liczy) i podsumowania numeryczne as.numeric()
- - - co jest błędne , ponieważ ma poziomy współczynników numerycznych --- i (poprawne) podsumowanie as.numeric(as.character())
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-06 22:51:41
Za pomocą poniższego kodu można przekonwertować wszystkie kolumny ramki danych na cyfry (X jest ramką danych, którą chcemy przekonwertować):
as.data.frame(lapply(X, as.numeric))
A do konwersji całej macierzy na liczbową masz dwa sposoby: Albo:
mode(X) <- "numeric"
Lub:
X <- apply(X, 2, as.numeric)
Alternatywnie możesz użyć funkcji data.matrix
do konwersji wszystkiego na liczbę, chociaż pamiętaj, że czynniki mogą nie zostać przekonwertowane poprawnie, więc bezpieczniej jest najpierw przekonwertować wszystko na character
:
X <- sapply(X, as.character)
X <- data.matrix(X)
Zwykle użyj tej ostatniej Jeśli chcę konwertować jednocześnie na macierz i cyfrę
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-04 10:34:35
Jeśli napotkasz 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 zadziała.
Rozwiązaniem potencjalnym jest:
as.numeric(gsub(",", ".", dat$x))
Uważam, że jest to dość powszechne w niektórych krajach nieangielskojęzycznych.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 14:12:13
Sposób uniwersalny 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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-10 05:35:29
Aby przekonwertować kolumnę ramki danych na numeryczną wystarczy wykonać: -
Współczynnik do liczb:-
data_frame$column <- as.numeric(as.character(data_frame$column))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-18 07:25:01
Chociaż inni dość dobrze omówili ten temat, chciałbym dodać tę dodatkową szybką myśl / podpowiedź. Możesz użyć wyrażenia regularnego, aby sprawdzić z góry, 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)
Dla bardziej wyrafinowanych wyrażeń regularnych i zgrabny dlaczego uczyć się/doświadczyć ich mocy zobaczyć tę naprawdę fajną stronę: http://regexr.com/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 09:58:44
Biorąc pod uwagę, że mogą istnieć kolumny znaków, jest to oparte na @Abdou w Automatycznie pobieraj typy kolumn arkusza excel odpowiedź:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-04 21:31:00
W moim PC (R v. 3.2.3), apply
lub sapply
Podaj błąd. Działa dobrze.
dt[,2:4] <- lapply(dt[,2:4], function (x) as.factor(as.numeric(x)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-11 05:53:10
Jeśli ramka danych ma wiele typów kolumn, niektóre znaki, niektóre liczby, spróbuj wykonać następujące czynności, aby przekonwertować tylko kolumny zawierające wartości liczbowe na 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])
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 22:08:26
Z hablar:: convert
Aby łatwo przekonwertować wiele kolumn na różne typy danych, możesz użyć hablar::convert
. Prosta składnia: df %>% convert(num(a))
konwertuje kolumnę a z df na liczbową.
Szczegółowy przykład
Pozwala skonwertować 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))
Wyniki w:
# 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-04 11:02:14
Aby przekonwertować znak na cyfrę, musisz przekonwertować go na współczynnik przez zastosowanie
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ę, wyświetli 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 Zastosuj
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
Pomyślnie przetworzy znak na cyfrę
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-17 21:05:30
df
to twoja ramka danych. x
jest kolumną df
chcesz przekonwertować
as.numeric(factor(df$x))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-04 17:41:59
Jeśli nie zależy ci na zachowaniu czynników i chcesz zastosować je do dowolnej kolumny, która może zostać przekonwertowana na liczbę, użyłem poniższego skryptu. jeśli df jest twoją oryginalną ramką danych, możesz użyć poniższego skryptu.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-19 02:45:18