我用的是prcomp功能時,我收到此錯誤去除R中恆列
Error in prcomp.default(x, ...) :
cannot rescale a constant/zero column to unit variance
我知道我可以手動掃描我的數據,但有R中的任何功能或命令,可以幫助我消除這些常量變量? 我知道這是一個非常簡單的任務,但我從來沒有遇到任何這樣做的功能。
謝謝,
我用的是prcomp功能時,我收到此錯誤去除R中恆列
Error in prcomp.default(x, ...) :
cannot rescale a constant/zero column to unit variance
我知道我可以手動掃描我的數據,但有R中的任何功能或命令,可以幫助我消除這些常量變量? 我知道這是一個非常簡單的任務,但我從來沒有遇到任何這樣做的功能。
謝謝,
這裏的問題是,你的列方差等於零。您可以檢查該數據幀的列是恆定的這種方式,例如:
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]
我想這個問答& A是一個受歡迎的谷歌的搜索結果,但答案是一個大的矩陣有點慢,再加上我沒有足夠的信譽第一的回答進行評論。因此我發佈了一個新的問題答案。
對於大矩陣的每一列,檢查最大值是否等於最小值就足夠了。
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
由於這種問答& A是一個受歡迎的谷歌的搜索結果,但答案是一個大的矩陣有點慢,@raymkchow版本與港定居慢我使用指數搜索和data.table
功率提出了一個新的版本。
這是我在dataPreparation包中實現的一個函數。
首先建立一個爲例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 <- 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
結果如下:
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倍其他方法。
加上更多的行,你有更多的使用intersting。
請閱讀發佈指南,並提供一個小的,可重現的樣本'x'。現在我們甚至不知道你的'x'是數字,更不用說矩陣。現在,如果它是一個矩陣,'y < - x [,sd(x)!= 0]'就足夠了。 – 2013-02-25 14:19:43
如果你在你的數據上使用prcomp,可能沒有必要,但是如果你確實有混合列類型,一個簡單的解決方案是'x [,apply(x,2,function(col){length(unique(col))> 1 })]' – 2015-07-26 11:40:07