2013-02-25 17 views
21

Ben prcomp fonksiyonu kullanılarak olduğunu bana bu kaldırmak yardımcı olabilir sabit değişkenler? Bunun çok basit bir görev olduğunu biliyorum, ancak bunu yapan herhangi bir işle hiç karşılaşmadım.çıkarılması

sayesinde

+1

Lütfen gönderim yönergelerini okuyun ve küçük, tekrarlanabilir bir örnek x işlevi sağlayın. Şu anda, 'x' inizin bir matris olmasına rağmen sayısal olup olmadığını bile bilmiyoruz. Şimdi, eğer bir matris ise, 'y <- x [, sd (x)! = 0]' yeterli olacaktır. –

+1

Verilerinizi önceden kullanıyorsanız, ancak karışık sütun türleriniz varsa, basit bir çözüm, x [, uygula (x, 2, function (col) {length (unique (col))> 1 ise, muhtemelen gerekli değildir. })] ' –

cevap

35

Buradaki sorun Sütun varyans sıfıra eşit olmasıdır. Örneğin, bu şekilde sabit olan bir veri çerçevesinin sütun kontrol edebilirsiniz:

df <- data.frame(x=1:5, y=rep(1,5)) 
df 
# x y 
# 1 1 1 
# 2 2 1 
# 3 3 1 
# 4 4 1 
# 5 5 1 

# Supply names of columns that have 0 variance 
names(df[, sapply(df, function(v) var(v, na.rm=TRUE)==0)]) 
# [1] "y" 

Yani bu sütunları hariç tutmak istiyorsanız, kullanabilirsiniz:

df[,sapply(df, function(v) var(v, na.rm=TRUE)!=0)] 

DÜZENLEME: Aslında Bunun yerine apply kullanmak daha basittir. Böyle bir şey:

df[,apply(df, 2, var, na.rm=TRUE) != 0] 
+0

Yukarıdaki yorumdaki minisolution değerinden daha hızlı mı (veya daha sağlam mı)? - Bunun dışında sd' :-) –

+1

@CarlWitthoft ile resmi olarak kullanım dışı bir işlem kullanıyorum, çünkü sd (x) kullandığınız zamanki tavsiyeyi kullanacağım 'apply (x, 2, sd) ' , Bence bu tamamen aynı, eğer tavsiyeyi takip ederseniz :) – juba

+0

mükemmel cevap, teşekkürler – zach

9

Bu Q & A popüler bir Google arama sonucu ama cevap büyük matris için biraz yavaş, artı ben ilk yanıt yorumlamak yeterli itibar yok sanırım. Bu yüzden soruya yeni bir cevap gönderiyorum.

Büyük bir matrisin her bir sütununda, maksimum değerin minimum değere eşit olup olmadığını kontrol etmek yeterlidir.

df[,!apply(df, MARGIN = 2, function(x) max(x, na.rm = TRUE) == min(x, na.rm = TRUE))] 

Bu bir testtir. İlk cevapla karşılaştırıldığında zamanın% 90'ından fazlası azalır. Ayrıca soruya verilen ikinci yorumdan da daha hızlıdır.

ncol = 1000000 
nrow = 10 
df <- matrix(sample(1:(ncol*nrow),ncol*nrow,replace = FALSE), ncol = ncol) 
df[,sample(1:ncol,70,replace = FALSE)] <- rep(1,times = nrow) # df is a large matrix 

time1 <- system.time(df1 <- df[,apply(df, 2, var, na.rm=TRUE) != 0]) # the first method 
time2 <- system.time(df2 <- df[,!apply(df, MARGIN = 2, function(x) max(x, na.rm = TRUE) == min(x, na.rm = TRUE))]) # my method 
time3 <- system.time(df3 <- df[,apply(df, 2, function(col) { length(unique(col)) > 1 })]) # Keith's method 

time1 
# user system elapsed 
# 22.267 0.194 22.626 
time2 
# user system elapsed 
# 2.073 0.077 2.155 
time3 
# user system elapsed 
# 6.702 0.060 6.790 
all.equal(df1, df2) 
# [1] TRUE 
all.equal(df3, df2) 
# [1] TRUE 
+1

Yeniden yapılandırdım ve maksimum ve min. işlemek yerine tümünün (x == x [1], na.rm = TRUE) kullanılması yaklaşık% 15 daha hızlıdır. – DavidR

+0

Pozisyon (fonksiyon (x)! Is.na (x), x) ilk na-olmayan elemanın indeks pozisyonunu verir ve eğer x'in bazı na değerleri varsa, bu daha fazla zaman harcar. – raymkchow

1

bu Q & A popüler bir Google arama sonucu ama cevap büyük matris için biraz yavaş ve @raymkchow versiyon i üstel arama ve data.table gücünü kullanarak yeni bir sürümünü önermek ilgi UA ile yavaş olduğu için.

Bu, dataPreparation paketinde uyguladığım bir işlevdir.

time1 <- system.time(df1 <- df[,apply(df, 2, var, na.rm=TRUE) != 0, with = F]) # the first method 
time2 <- system.time(df2 <- df[,!apply(df, MARGIN = 2, function(x) max(x, na.rm = TRUE) == min(x, na.rm = TRUE)), with = F]) # raymkchow 
time3 <- system.time(df3 <- df[,apply(df, 2, function(col) { length(unique(col)) > 1 }), with = F]) # Keith's method 
time4 <- system.time(df4 <- df[,-whichAreConstant(df, verbose=FALSE)]) # My method 

sonuçları:

Önce bir exemple (genellikle durum) sütun daha çizgilerle data.table ve UA

ncol = 1000 
nrow = 100000 
df <- matrix(sample(1:(ncol*nrow),ncol*nrow,replace = FALSE), ncol = ncol) 
df <- apply (df, 2, function(x) {x[sample(c(1:nrow), floor(nrow/10))] <- NA; x}) # Add 10% of NAs 
df[,sample(1:ncol,70,replace = FALSE)] <- rep(1,times = nrow) # df is a large matrix 
df <- as.data.table(df) 

sonra kıyaslama% 10 bütün yaklaşımlar oluşturmak şunlardır:

time1 # Variance approch 
# user system elapsed 
# 2.55 1.45 4.07 
time2 # Min = max approach 
# user system elapsed 
# 2.72  1.5 4.22 
time3 # length(unique()) approach 
# user system elapsed 
# 6.7 2.75 9.53 
time4 # Exponential search approach 
# user system elapsed 
# 0.39 0.07 0.45 
all.equal(df1, df2) 
# [1] TRUE 
all.equal(df3, df2) 
# [1] TRUE 
all.equal(df4, df2) 
# [1] TRUE 

dataPreparation:whichAreConstant o 10 kat daha hızlıdır o yaklaşımlar.

Ayrıca, daha fazla aralığa sahip olduğunuz daha fazla satır var.

İlgili konular