Yanıtlar:
(Hala) kimse onay işareti almadığından, aklınızda bazı pratik sorunlarınız olduğunu varsayıyorum, çünkü çoğunlukla ne tür bir vektöre dönüştürmek istediğinizi belirtmediniz numeric
. transform
Görevinizi tamamlamak için işlevi uygulamanızı öneririm .
Şimdi belirli "dönüşüm anomalilerini" göstermek üzereyim:
# 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)
Bir bakış atalım 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
ve koşalım:
> 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"
Şimdi muhtemelen kendinize "Anomali nerede?" Diye soruyorsunuz. Eh, Ar oldukça tuhaf şeyler çarptı ettik ve bu değil en karıştırıcı şey, ama yatağına yuvarlanan önce okumak, özellikle de sizi şaşırtmak olabilir.
İşte gidiyor: ilk iki sütun character
. Kasten 2. birini aradım fake_char
. Bu character
değişkenin benzerliğini Dirk'in cevabında yarattığı değişkenle tespit edin. Aslında numerical
dönüştürülmüş bir vektör character
. 3 üncü ve 4 inci sütun olan factor
ve son bir "saf" dir numeric
.
transform
Fonksiyonu kullanırsanız , değişkenin fake_char
içine numeric
değil, içine dönüştürebilirsiniz 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
ama eğer aynı şeyi yaparsanız fake_char
ve char_fac
şanslı olursunuz ve NA'lar olmadan uzaklaşırsınız:
> 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
Eğer dönüştürülmüş tasarruf ederse data.frame
ve kontrol mode
ve class
elde edersiniz:
> 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"
Sonuç olarak: Evet, character
vektörü bir taneye dönüştürebilirsiniz numeric
, ancak yalnızca öğeleri "dönüştürülebilir" ise numeric
. Vektörde yalnızca bir character
öğe varsa , o vektörü numerical
bire dönüştürmeye çalışırken hata alırsınız .
Ve sadece benim fikrimi kanıtlamak için:
> 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
Ve şimdi, sadece eğlence için (veya pratik), bu komutların çıktısını tahmin etmeye çalışın:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Saygılarımla, Patrick Burns! =)
Bana yardımcı olan bir şey: dönüştürmek için değişken aralığınız varsa (veya sadece bir taneden fazla), kullanabilirsiniz sapply
.
Biraz saçma ama sadece örneğin:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Diyelim ki 3, 6-15 ve 37 numaralı sütunlarınız veri çerçevesinin sayısal olana dönüştürülmesi gerekiyor:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapply
aramayı as.data.frame()
sağ taraftaki @Mehrad Mahmoudian aşağıda önerildiği gibi, işe yarayacak.
veri x
çerçevesinin sütun adı dat
ve x
tür faktörü ise, şunu kullanın:
as.numeric(as.character(dat$x))
as.character
gerçekten aradığım şeydir. Aksi takdirde dönüşüm bazen yanlış olur. En azından benim durumumda.
Error: (list) object cannot be coerced to type 'double'
Vektörimin karakterleri / noktalama işaretleri olmadığından makul bir şekilde emindim. Sonra denedim as.numeric(as.character(dat$x))
ve işe yaradı. Şimdi sütunum aslında sadece tamsayı olup olmadığından emin değilim!
Sorunuz kesinlikle sayısal olsa da, R'yi başlatırken anlaşılması zor olan birçok dönüşüm var. Yardımcı olacak yöntemleri ele almayı hedefleyeceğim. Bu soru benzer Bu Soru .
Tür dönüşümü R'de bir acı olabilir, çünkü (1) faktörler doğrudan sayıya dönüştürülemez, önce karakter sınıfına dönüştürülmeleri gerekir, (2) tarihler genellikle ayrı ayrı ele almanız gereken özel bir durumdur ve (3) veri çerçevesi sütunları arasında döngü yapmak zor olabilir. Neyse ki, "düzenli" çoğu sorunu çözdü.
Bu çözüm, mutate_each()
veri çerçevesindeki tüm sütunlara bir işlev uygulamak için kullanılır. Bu durumda, type.convert()
dizeleri olabildiğince sayısal biçime dönüştüren işlevi uygulamak istiyoruz . Çünkü R, faktörleri seviyor (neden olduğundan emin değilim) karakterde kalması gereken karakter sütunları faktöre dönüştürülür. Bunu düzeltmek için mutate_if()
işlev, faktör olan ve karakter olarak değişen sütunları algılamak için kullanılır. Son olarak, lubridate'in karakter sınıfındaki bir zaman damgasını tarih-zamana değiştirmek için nasıl kullanılabileceğini göstermek istedim, çünkü bu aynı zamanda yeni başlayanlar için yapıştırma bloğudur.
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)
Bunun yerine kullanırsanız , komutu kısaltmak mutate_all(type.convert)
/ mutate_if(is.factor, as.character)
kısaltmak için kullanabileceğinizi unutmayın . as.is
, type.convert()
dizeleri karakter olarak mı yoksa faktör olarak mı dönüştüreceğini belirten bir bağımsız değişkendir . Varsayılan olarak, as.is=FALSE
in type.convert()
(yani, dizeleri karakter sınıfı yerine faktör sınıfına dönüştürür).
Tim haklıdır ve Shane'nin bir ihmali vardır. İşte ek örnekler:
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>
Bizim data.frame
şimdi faktör sütununa (sayımlar) ve sayısal özetleri bir özeti vardır as.numeric()
olduğunu --- yanlış o sayısal faktör şekilde boşalır olarak --- ve (doğru) özetini as.numeric(as.character())
.
Aşağıdaki kodla, tüm veri çerçevesi sütunlarını sayıya dönüştürebilirsiniz (X, sütunlarını dönüştürmek istediğimiz veri çerçevesidir):
as.data.frame(lapply(X, as.numeric))
ve tüm matrisi sayısal hale dönüştürmek için iki yolunuz vardır:
mode(X) <- "numeric"
veya:
X <- apply(X, 2, as.numeric)
Alternatif olarak, data.matrix
her şeyi sayısal hale getirmek için işlevi kullanabilirsiniz , ancak faktörlerin doğru dönüştürülemeyebileceğini unutmayın, bu nedenle her şeyi character
önce dönüştürmek daha güvenlidir :
X <- sapply(X, as.character)
X <- data.matrix(X)
Genellikle kullanmak bu sonuncuyu ben istersem aynı anda matris ve sayısal için dönüştürmek
Şununla ilgili sorun yaşarsanız:
as.numeric(as.character(dat$x))
Ondalık işaretlerinize bir göz atın. "" Yerine "," ise. (örn. "5,3") yukarıdaki işe yaramaz.
Potansiyel bir çözüm:
as.numeric(gsub(",", ".", dat$x))
Bunun İngilizce bilmeyen bazı ülkelerde oldukça yaygın olduğuna inanıyorum.
Evrensel yolu kullanarak type.convert()
ve 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
Karakterinizi sayısal veya faktörlere dönüştürmek istiyorsanız kaldırın
matrix
sayısal değişikliklere classes=matrix
yazılan sütun demetini değiştirmeye çalışmak mod karakteri olmalıdır
Bir veri çerçevesi sütununu sayısal olarak dönüştürmek için yapmanız gerekenler: -
faktör - sayısal: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Diğerleri konuyu oldukça iyi ele almış olsa da, bu ek hızlı düşünceyi / ipucunu eklemek istiyorum. Karakterlerin potansiyel olarak sadece rakamlardan oluşup oluşmadığını önceden kontrol etmek için regexp kullanabilirsiniz.
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)
Daha sofistike düzenli ifadeler ve güçlerini neden öğrenmek / deneyimlemek için düzgün bir şekilde bu gerçekten güzel web sitesine bakın: http://regexr.com/
Karakter sütunları olabileceği düşünüldüğünde, bu, Excel sayfasının sütun türlerini otomatik olarak yanıtla bölümündeki @ Abdou'ya dayanır :
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)
Veri çerçevesinde birden fazla sütun türü, bazı karakterler varsa, bazıları sayısal olarak yalnızca sayısal değerler içeren sütunları sayısal olarak dönüştürmek için aşağıdakileri deneyin:
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])
}
}
ile hablar :: convert
Birden çok sütunu farklı veri türlerine kolayca dönüştürmek için kullanabilirsiniz hablar::convert
. Basit sözdizimi: df %>% convert(num(a))
a sütununu df'den sayıya dönüştürür.
Ayrıntılı örnek
Öğesinin tüm sütunlarını mtcars
karaktere dönüştürelim .
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
İle hablar::convert
:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
sonuç:
# 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
Karakteri sayısal hale dönüştürmek için, uygulayarak faktöre dönüştürmeniz gerekir.
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Aynı sütuna sahip iki sütun oluşturmanız gerekir, çünkü bir sütun sayıya dönüştürülemez. Bir dönüşüm yaparsanız aşağıdaki hatayı verir
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
yani, aynı verilerin iki sütununu yaptıktan sonra
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
karakteri sayıya başarıyla dönüştürecek
df
veri çerçeveniz. dönüştürmek istediğiniz x
bir sütundf
as.numeric(factor(df$x))
Faktörleri korumakla ilgilenmiyorsanız ve bunu sayıya dönüştürülebilecek herhangi bir sütuna uygulamak istiyorsanız, aşağıdaki komut dosyasını kullandım. df orijinal veri çerçevenizse, aşağıdaki komut dosyasını kullanabilirsiniz.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))