[英]R - Remove the Columns from a data-frame if they are Identical
我有一個數據框,其中包含100多個列和10000行。 如果該列中的所有行都相同,則手動檢查每一列中的數據,然后將其刪除變得更加困難。
因此,我正在尋找一個將數據框作為輸入並輸出另一個數據框的函數,該數據框將僅具有不相同的列。
輸入數據幀將類似於:
data<- read.table(text = "
A B C D
1 1 3 4
1 2 2 4", header = TRUE)
我希望輸出數據幀為:
B C
1 3
2 2
謝謝。
一種選擇是Filter
以僅保留其unique
元素length
大於1的列
Filter(function(x) length(unique(x))>1, data)
# B C
#1 1 3
#2 2 2
或另一個選擇是sapply
data[sapply(data, function(x) length(unique(x)))>1]
或與anyDuplicated
data[!sapply(data, anyDuplicated)]
只是在這里添加一些選項:
如果所有元素都相同,則意味着最小值和最大值將相同。 請注意,這些是高度優化的內置函數。 同樣,如果所有元素都相同,則方差為0。在代碼中:
df[, !sapply(df, function(x) min(x) == max(x))]
df[, !sapply(df, function(x) var(x) == 0)] # if all numeric
如果是性能問題,我們來比較一下:
# 100 columns and 10000 rows with duplicates:
df <- data.frame(
matrix(rnorm(10000*50),ncol=50), # 50 columns, non-repeating
matrix(1:50, ncol=50)[rep(1,10000),] # 50 columns, identical elements
)
ak <- function(){
Filter(function(x) length(unique(x))>1, df)
}
ak2 <- function(){
df[sapply(df, function(x) length(unique(x)))>1]
}
ak3 <- function(){
df[!sapply(df, anyDuplicated)]
}
cj <- function(){
df[, !sapply(df, function(x) var(x) == 0)]
}
cj2 <- function(){
df[, !sapply(df, function(x) min(x) == max(x))]
}
library(microbenchmark)
microbenchmark(ak(), ak2(), ak3(), cj(), cj2())
Unit: milliseconds
expr min lq mean median uq max neval
ak() 17.472319 17.870399 19.586547 19.040228 19.762838 66.545086 100
ak2() 17.412296 18.152165 19.830981 19.127153 19.908074 65.856221 100
ak3() 11.359604 11.608405 12.475312 11.939775 12.966077 18.132573 100
cj() 6.799404 7.043694 7.466027 7.175871 7.472253 10.451793 100
cj2() 4.068508 4.237848 4.306551 4.279522 4.373600 4.901368 100
內置的min
和max
函數應該進行高度優化,這說明了良好的性能。 考慮到涉及到許多計算,我很驚訝var == 0
這么好(計算平均值,從所有元素中減去平均值,對結果求和,求和)。
使用sapply
瀏覽每列。 然后,對於每一列,檢查所有元素是否等於第一個元素。
data[!sapply(data, function(x) all(x == x[1]))]
# B C
#1 1 3
#2 2 2
微microbenchmark
測試的結果如下所示。 請注意,在這種情況下, db()
為
db = function(){
df[!sapply(df, function(x) all(x == x[1]))]
}
所有其他功能和數據均來自coffeinjunky的答案 。
with(microbenchmark(db(), ak(), ak2(), ak3(), cj(), cj2()),
boxplot(x = split(time/1e6, expr), outline = FALSE, ylab = "milliseconds"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.