簡體   English   中英

R-如果數據列相同,則從數據框中刪除這些列

[英]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

內置的minmax函數應該進行高度優化,這說明了良好的性能。 考慮到涉及到許多計算,我很驚訝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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM