2013-02-25 33 views
21

जब मैं इस त्रुटिहटाने

Error in prcomp.default(x, ...) : 
cannot rescale a constant/zero column to unit variance 

मैं जानता हूँ कि मैं मैन्युअल रूप से अपने डेटा को स्कैन लेकिन वहाँ आर में किसी भी कार्य या आदेश है सकते हैं प्राप्त मैं prcomp समारोह उपयोग कर रहा था कि मुझे इन हटाने में मदद कर सकते निरंतर चर? मुझे पता है कि यह एक बहुत ही आसान काम है, लेकिन मैं कभी भी ऐसा कोई काम नहीं कर रहा हूं जो ऐसा करता है।

धन्यवाद,

+1

कृपया पोस्टिंग दिशानिर्देश पढ़ें, और एक छोटा, पुनरुत्पादित नमूना 'x' प्रदान करें। अभी हम यह भी नहीं जानते कि आपका 'x' संख्यात्मक है, अकेले मैट्रिक्स दें। अब, यदि यह एक मैट्रिक्स है, 'y <- x [, sd (x)! = 0]' पर्याप्त होगा। –

+1

यदि आप अपने डेटा पर prcomp का उपयोग कर रहे हैं, तो शायद आवश्यक नहीं है, लेकिन यदि आपके पास मिश्रित कॉलम प्रकार हैं, तो एक सरल समाधान 'x [, लागू (x, 2, फ़ंक्शन (कोल) {लंबाई (अद्वितीय (कोला))> 1 })] ' –

उत्तर

35

समस्या यहां है कि आपके स्तंभ विचरण शून्य के बराबर है। आप देख सकते हैं जो एक डेटा फ्रेम के स्तंभ इस तरह से स्थिर है, उदाहरण के लिए:

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" 

तो अगर आप इन स्तंभों को बाहर निकालना चाहते हैं, तो आप उपयोग कर सकते हैं:

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

संपादित करें: वास्तव में इसके बजाय apply का उपयोग करना आसान है। कुछ इस तरह:

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

ऊपर टिप्पणी में मेरे minisolution की तुलना में यह तेजी से (या अधिक मजबूत) है? - इसके अलावा मैं 'sd' :-) –

+1

@CarlWitthoft Well के साथ आधिकारिक रूप से बहिष्कृत ऑपरेशन का उपयोग कर रहा हूं, जब आप' sd (x) 'का उपयोग करते हैं तो सलाह' लागू (x, 2, sd) ' , मुझे लगता है कि यह काफी समान है, अगर आप सलाह का पालन करते हैं :) – juba

+0

महान उत्तर, धन्यवाद – zach

9

मुझे लगता है कि इस क्यू & एक लोकप्रिय Google खोज परिणाम है, लेकिन इस सवाल का जवाब एक बड़ी मैट्रिक्स के लिए थोड़ा धीमा है, के साथ साथ मैं पहली बार जवाब पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है। इसलिए मैं सवाल का एक नया जवाब पोस्ट करता हूं।

बड़े मैट्रिक्स के प्रत्येक कॉलम के लिए, यह जांचना कि अधिकतम न्यूनतम के बराबर है या नहीं।

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

यह परीक्षण है। पहले जवाब की तुलना में 90% से अधिक समय कम हो गया है। यह सवाल पर दूसरी टिप्पणी के जवाब से भी तेज है।

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

मैं फिर से चलाता हूं और पाया कि यह अधिकतम और न्यूनतम कंप्यूटिंग के बजाय सभी (x == x [1], na.rm = TRUE) का उपयोग करने के लिए लगभग 15% तेज है। – DavidR

+0

स्थिति (फ़ंक्शन (x)! Is.na (x), x) पहले गैर-ना तत्व की अनुक्रमणिका स्थिति देता है, और यदि x के कुछ मान हैं तो यह अधिक समय व्यतीत करता है। – raymkchow

1

के बाद से इस क्यू & एक लोकप्रिय Google खोज परिणाम है, लेकिन इस सवाल का जवाब एक बड़ी मैट्रिक्स के लिए थोड़ा धीमा है और @raymkchow संस्करण NAS के साथ धीमी है मैं घातीय खोज और data.table शक्ति का उपयोग एक नया संस्करण का प्रस्ताव।

यह एक फ़ंक्शन जिसे मैंने dataPreparation पैकेज में कार्यान्वित किया था।

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 

परिणाम:

पहले एक उदाहरण data.table, कॉलम की तुलना में अधिक लाइनों के साथ (जो आमतौर पर है मामले) और NAS

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) 

फिर बेंचमार्क का 10% सभी दृष्टिकोण का निर्माण निम्नलिखित हैं:

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 10 बार ओ की तुलना में तेजी है थर्म दृष्टिकोण

प्लस जितनी अधिक पंक्तियां आपके पास अधिक अंतरंग हैं, इसका उपयोग करना है।