Bir veri çerçevesi sütunu sayısal türe nasıl dönüştürülür?


Yanıtlar:


267

(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. transformGö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 characterdeğişkenin benzerliğini Dirk'in cevabında yarattığı değişkenle tespit edin. Aslında numericaldönüştürülmüş bir vektör character. 3 üncü ve 4 inci sütun olan factorve son bir "saf" dir numeric.

transformFonksiyonu kullanırsanız , değişkenin fake_chariçine numericdeğ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_charve 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.frameve kontrol modeve classelde 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, charactervektö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ü numericalbire 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! =)


6
'stringsAsFactors = FALSE' veri dosyalarında okurken önemlidir.
Robert Brisita

4
Bu eski olduğunu biliyorum ... ama ... neden df $ fake_char <- as.integer (df $ fake_char) üzerinden transform () seçtiniz? R'de aynı işlemi yapmanın birden fazla yolu vardır ve bunu yapmanın "doğru" yolunu anlamaya şaşırırım. Teşekkür ederim.
ripvlan

Yani hata <- c (1, "b", 3, 4, "e") sayısal bir vektöre dönüştürülemez mi? Excel'de, "sayıya dönüştürmenizi" sağlayan bir düğme vardır. sütuna herhangi bir değeri sayısal olarak yapma. Bunu r'de taklit etmeye çalışıyorum.
flightless13wings

Uyarı! = Hata. Karışık sayıyı / karakteri sayıya dönüştürürken bir hata almazsınız, bir uyarı ve bazı NA değerleri alırsınız.
Gregor Thomas

136

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)

1
Yukarıdaki koddaki
as.factor

1
Değişken isimlerden ziyade endekslerin vektörlerini kullanırken sapply dönüşümden daha iyidir
smci

@MySchizoBuddy, en azından verilerimle doğru. Orijinal df "dönüştürülmüş" sütunları faktör olarak kabul etmez; karakter olarak kalacaklar. Eğer sarın Eğer sapplyaramayı as.data.frame()sağ taraftaki @Mehrad Mahmoudian aşağıda önerildiği gibi, işe yarayacak.
knowah

Bu bir matris için işe yarar mı? Ben tam olarak aynı kod ile deniyorum, henüz sonra bir sütunun class () kontrol, hala "sayısal" ve "sayısal" diyor
namore

87

veri xçerçevesinin sütun adı datve xtür faktörü ise, şunu kullanın:

as.numeric(as.character(dat$x))

3
ekleyerek as.charactergerçekten aradığım şeydir. Aksi takdirde dönüşüm bazen yanlış olur. En azından benim durumumda.
Thieme Hennis

1
As.character neden gereklidir? Bir hata alıyordum: 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!
vagabond

2
As.numeric öğesini bir faktöre yaparsanız, düzeyler gerçek değerlere değil sayısal değere dönüştürülür. Bu nedenle, faktörü karaktere, sonra as.numeric'e dönüştürmek için as.character gereklidir
MySchizoBuddy

Bu en iyi cevap
mitoRibo

25

Bir yorum eklerdim (düşük derecelendirme yapamıyorum)

Kullanıcı276042 ve pangratz'a eklemek için

dat$x = as.numeric(as.character(dat$x))

Bu, mevcut x sütununun değerlerini geçersiz kılar


16

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=FALSEin type.convert()(yani, dizeleri karakter sınıfı yerine faktör sınıfına dönüştürür).
LC-datascientist

15

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()).


1
Zevkle. Bu, dilin daha saçma köşelerinden biridir ve bence buradaki eski 'R Gotchas' sorusunda yer aldı.
Dirk Eddelbuettel

14

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.matrixher ş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


12

Ş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.


8

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"

3
Bu en esnek çözüm - bazı upvotes hak ediyor!
Richard Border

En iyi cevap olmalı. as.is = TRUEKarakterinizi sayısal veya faktörlere dönüştürmek istiyorsanız kaldırın
qfazille

bir data.frame içinde ilk argümandan çıkarılan matrixsayısal değişikliklere classes=matrixyazılan sütun demetini değiştirmeye çalışmak mod karakteri olmalıdır
add-semi-colons

1
Bu konudaki en iyi cevap.
yuk

3

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))

Yine, bu cevap mevcut cevap kümesine hiçbir şey eklemez. Ayrıca, bir faktörü sayısal hale dönüştürmenin tercih edilen yolu değildir. Tercih edilen yöntem için stackoverflow.com/q/3418128 adresine bakın .
BenBarnes

Daha iyi bir cevap:sapply(data_frame,function(x) as.numeric(as.character(x)))
data-frame-gg

2

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/


1

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)

0

Bilgisayarımda (R v.3.2.3) applyveya sapplyhata verin. lapplyiyi çalışıyor.

dt[,2:4] <- lapply(dt[,2:4], function (x) as.factor(as.numeric(x)))

0

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])
  }
}

0

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ı mtcarskaraktere 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   

0

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


0

dfveri çerçeveniz. dönüştürmek istediğiniz xbir sütundf

as.numeric(factor(df$x))

0

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)))

Ben başvurulan Shane ve Joran en btw çözümü

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.