2015-10-05 21 views
14

Bir data.table cols alt kümesini yeni bir sınıfa dönüştürmek istiyorum. Burada popüler bir soru var (Convert column classes in data.table) ama cevap, başlangıç ​​nesnesinde çalışmak yerine yeni bir nesne oluşturur.data.table dosyasındaki * bazı * sütun sınıflarını dönüştürebilir

dat <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10)) 
cols <- c('ID', 'Quarter') 

nasıl en iyi (örn) bir faktör sadece cols sütunlara dönüştürmek için:

bu örnek alın?

dat[, cols] <- lapply(dat[, cols], factor) 

ama bu bir data.table için çalışmaz, ne de Matt Dowle bağlanan söz konusu bu

dat[, .SD := lapply(.SD, factor), .SDcols = cols] 

bir yorumunu yapar: Normal bir data.frame size bu yapabileceğini (Aralık 2013'ten itibaren), iyi çalışıyor, ama biraz daha az zarif görünüyor aşağıdakileri önerir.

for (j in cols) set(dat, j = j, value = factor(dat[[j]])) 

anda daha iyi bir data.table cevap var mı (yani bir karşı değişkeni oluşturmaz kısa +), ya da sadece yukarıdaki + rm(j) kullanmalıyım?

dat[, (cols) := lapply(.SD, factor), .SDcols=cols] 

:= kullanarak:

+0

Ben yöntem Matt Dowle iyi olurdu önerir inanıyoruz. Sonuçta, * data.table * yazarıdır. –

+1

Doğru, ama yorum 2013'ten beri ve o zamandan bu yana pek çok paket güncellemesi yapıldı, bu yüzden – arvi1000

+2

bu olta fırlatmaya değdiğini düşündüğüm için "(()) set (...)' deyiminde daha fazla ayrıntı eklendi Son zamanlarda burada: http://stackoverflow.com/a/33000778/403310 –

cevap

26

seçeneğini kullanarak yanında Matt Dowle önerdiği gibi, kolon sınıfları değiştirmenin başka bir yoludur operatörü referans ile güncelleyin. aynı sonucu verecektir

for (col in cols) set(dat, j = col, value = factor(dat[[col]])) 

: Bu çalıştı olmadığını bir onay şu şekildedir:

yorumlarda @MattDowle tarafından suggeted gibi
> sapply(dat,class) 
     ID Quarter  value 
"factor" "factor" "numeric" 

, ayrıca for(...) set(...) bir arada kullanabilirsiniz. for(...) set(...) seçenek lapply seçenek göre yaklaşık üç kat daha hızlı olduğunu, daha küçük veri kümeleri üzerinde

for (col in cols) dat[, (col) := factor(dat[[col]])] 

(ama küçük bir veri kümesi tutar olduğundan, gerçekten önemli değil): Üçüncü bir alternatiftir. Daha büyük veri kümelerinde (ör. 2 milyon satır), bu yaklaşımların her biri yaklaşık aynı süreyi alır. Daha büyük bir veri kümesi üzerinde test için kullandığım:

dat <- data.table(ID=c(rep("A", 1e6), rep("B",1e6)), 
        Quarter=c(1:1e6, 1:1e6), 
        value=rnorm(10)) 

Bazen, (sayısal değerler bir faktör olarak saklanır zaman örneğin) farklı bunu biraz yapmak zorunda kalacaktır.O zaman böyle bir şey kullanmak zorunda:

dat[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols=cols] 


UYARI: Aşağıdaki açıklama değil şeyler yapmanın data.table -way olan. Bir kopya, bellek kullanımını arttıran ve bellekte saklanan bellekte saklandığından (@Frank tarafından işaret edildiği gibi) referans ile güncellenmemektedir. with=FALSE'un çalışmasını açıklamak için daha fazla bir ek. Eğer bir dataframe ile yapacağı gibi sütun sınıflara aynı şekilde değiştirmek istediğinizde aşağıdaki gibi

, sen with = FALSE eklemek zorunda:

dat[, cols] <- lapply(dat[, cols, with = FALSE], factor) 

bu çalışıp çalışmadığı konusunda bir onay:

> sapply(dat,class) 
     ID Quarter  value 
"factor" "factor" "numeric" 

with = FALSE'u eklemezseniz, datatable dat[, cols] değerini vektör olarak değerlendirir. dat[, cols] ve dat[, cols, with=FALSE] arasındaki çıktısında fark edin:

> dat[, cols] 
[1] "ID"  "Quarter" 

> dat[, cols, with=FALSE] 
    ID Quarter 
1: A  1 
2: A  2 
3: A  3 
4: A  4 
5: A  5 
6: B  1 
7: B  2 
8: B  3 
9: B  4 
10: B  5 
+1

Bence kullanmak istemiyorsun <-'. Eğer 'address()' işlevini önce ve sonra çalıştırırsam, bu değişiklik referans olarak değil gibi görünmektedir ([<-. Data.table' bu kullanımı kapsadığı halde). – Frank

+1

@Frank Biliyorum, ancak bir veritabanın bir veri çerçevesiyle aynı şekilde döndürülmesi için bir datatable istediğinizde neden 'FALSE 'ile niçin gerektiğini açıklamak için öncelikle ikinci kısmı ekledim. Bir uyarı ekledim. – Jaap

+0

Evet, nasıl çalıştığını biliyorum, ancak işaret ettiğin gibi bu "data.table" yerel yolu değil. Ana cevap için teşekkürler – arvi1000

1

Sen .SDcols kullanabilirsiniz: aşağıdaki gibi

dat[, cols] <- dat[, lapply(.SD, factor), .SDcols=cols]

+0

Bu, downvotes almanın bir nedeni var mı? Bu sonuca ulaşmak için askerden – Chris

+1

aradığı sonucu aldığım diğer yanıtla aynı. Bir data.table kullanmanın büyük bir avantajı, referans olarak değişiklik yapmaktır, ancak söyleyebildiğim kadarıyla, [<-'ile bir tanesi bundan yararlanamamaktadır. – Frank

+0

@Chris kullanıcıları burada "kısa cevap yok" kılavuzunu biraz fazla ciddiye alıyorlar. Her ne kadar genişlemek/açıklamak için neredeyse her zaman yer var. – shadowtalker

İlgili konular