我有一个数据框,有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
感谢。
答案 0 :(得分:4)
一个选项是Filter
,只保留其length
元素unique
大于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)]
答案 1 :(得分:4)
在这里添加一些选项:
如果所有元素都相同,则表示最小值和最大值相同。请注意,这些是高度优化的内置函数。同样,如果所有元素都相同,则方差为0.在代码中:
$ docker images | grep test-tgz
test-tgz-curl latest 2776133659af 30 seconds ago 269MB
test-tgz-add latest d625455998ff 2 minutes ago 359MB
如果是性能问题,那就让我们进行比较:
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
做得很好。
答案 2 :(得分:3)
使用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's answer。
with(microbenchmark(db(), ak(), ak2(), ak3(), cj(), cj2()),
boxplot(x = split(time/1e6, expr), outline = FALSE, ylab = "milliseconds"))