【问题标题】:Remove rows with the same value across all columns删除所有列中具有相同值的行
【发布时间】:2017-11-07 22:58:13
【问题描述】:

假设我有一个如下所示的数据框 (df):

options(stringsAsFactors = F)

cars <- c("Car1", "Car2", "Car3", "Car4", "Car5", "Car6", "Car7", "Car8", "Car9")
test1 <- c(0,0,3,1,4,2,1,3,0)
test2 <- c(0,0,2,1,0,2,2,5,0)
test3 <- c(1,0,5,1,2,2,6,7,0)
test4 <- c(2,NA,2,1,2,2,1,1,0)
test5 <- c(0,0,1,1,0,2,1,3,0)
test6 <- c(1,0,1,1,1,2,3,4,0)
test7 <- c(3,0,2,1,0,2,1,1,0)

df <- data.frame(cars,test1,test2,test3,test4,test5,test6,test7)

#df
   cars test1 test2 test3 test4 test5 test6 test7
#1 Car1     0     0     1     2     0     1     3
#2 Car2     0     0     0    NA     0     0     0
#3 Car3     3     2     5     2     1     1     2
#4 Car4     1     1     1     1     1     1     1
#5 Car5     4     0     2     2     0     1     0
#6 Car6     2     2     2     2     2     2     2
#7 Car7     1     2     6     1     1     3     1
#8 Car8     3     5     7     1     3     4     1
#9 Car9     0     0     0     0     0     0     0

我想删除整行中具有相同值的所有行(在上面的示例中,我想保留第 1、3、5、7、8 行并删除其余行)。

我已经想出了如何删除所有有零的行

 df$sum <- rowSums(df[,c(2:8)], na.rm = T )
 df.all0 <- df[which(df$sum == 0),]

但是,这不一定适用于所有其他行。与其他问题不同,此问题要求在整行中查找重复项,而不仅仅是特定列。

任何帮助将不胜感激!

【问题讨论】:

  • @akaDrHouse 我看不出我的问题是如何重复的。我问的是整行,而不是列中的一些重复项。
  • 你是对的;我误会了。对此感到抱歉。
  • 熊猫有这样的东西吗?

标签: r dataframe


【解决方案1】:
keep <- apply(df[2:8], 1, function(x) length(unique(x[!is.na(x)])) != 1)
df[keep, ]

  cars test1 test2 test3 test4 test5 test6 test7
1 Car1     0     0     1     2     0     1     3
3 Car3     3     2     5     2     1     1     2
5 Car5     4     0     2     2     0     1     0
7 Car7     1     2     6     1     1     3     1
8 Car8     3     5     7     1     3     4     1

【讨论】:

  • 嗨@JasonWang!保存已删除行的汽车 ID 的最佳方法是什么?
  • which(!keep) 会给你你删除的行索引。
【解决方案2】:

这是rowSums 的选项;逻辑是检查行中是否有任何值与您感兴趣的列之一不同(NA 不计算在内):

df[rowSums(df[-1] != df[[2]], na.rm = TRUE) != 0,]

#  cars test1 test2 test3 test4 test5 test6 test7
#1 Car1     0     0     1     2     0     1     3
#3 Car3     3     2     5     2     1     1     2
#5 Car5     4     0     2     2     0     1     0
#7 Car7     1     2     6     1     1     3     1
#8 Car8     3     5     7     1     3     4     1

【讨论】:

  • 嗨!谢谢你的想法。我有点被你的逻辑弄糊涂了。你是说你将所有列与 test1 列进行比较?
  • 哦等等!我觉得我明白了。您使用 test1 作为参考点来检查所有其他列是否具有相同的值(或不同)。对吗?
  • 是检查所有 test 列与 test1,如果有一列具有不同的非 NA 值,则 rowSums 将不同于零,因此您将保留它。
【解决方案3】:

我们也可以使用MapReduce

df[c(Reduce(`+`, Map(function(x,y) x != y & !is.na(x), df[-1], list(df[2]))) != 0),]
#  cars test1 test2 test3 test4 test5 test6 test7
#1 Car1     0     0     1     2     0     1     3
#3 Car3     3     2     5     2     1     1     2
#5 Car5     4     0     2     2     0     1     0
#7 Car7     1     2     6     1     1     3     1
#8 Car8     3     5     7     1     3     4     1

或者使用tidyverse

library(tidyverse)
df %>% 
    filter_at(vars(starts_with("test")), any_vars((. != test1)))
#   cars test1 test2 test3 test4 test5 test6 test7
#1 Car1     0     0     1     2     0     1     3
#2 Car3     3     2     5     2     1     1     2
#3 Car5     4     0     2     2     0     1     0
#4 Car7     1     2     6     1     1     3     1
#5 Car8     3     5     7     1     3     4     1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多