【问题标题】:Extract rows that have duplicates for certain column but are unique in another column提取某些列重复但在另一列中唯一的行
【发布时间】:2017-12-05 17:25:47
【问题描述】:

我正在 R 中进行一些编码。我想显示列 ID 和 NAME 重复但 AGE 值不同的行。

例如我有这张桌子:

ID |    NAME | AGE
111|     Mark| 22
222|     Anne| 21
333|    Chery| 30
444|    Megan| 16
555|  Charles| 37
111|     Mark| 23
222|     Anne| 22
333|    Chery| 30
111|     Mark| 22

到目前为止,我有这个代码:

readfile <- read.csv(file='/home/user/shane/names.csv')
dat <- data.frame(ID=c(readfile$ID),NAME=c(readfile$NAME),AGE=c(readfile$AGE))
nam <- duplicated(dat[,c('ID','NAME)]) | duplicated(dat[,c('ID','NAME], fromLast = TRUE)
readfile[nam,]

输出如下:

ID |    NAME | AGE
111|     Mark| 22
222|     Anne| 21
333|    Chery| 30
111|     Mark| 23
222|     Anne| 22
333|    Chery| 30
111|     Mark| 22

我希望输出为:

ID |    NAME | AGE
111|     Mark| 22
222|     Anne| 21
111|     Mark| 23
222|     Anne| 22
111|     Mark| 22

我想删除 ID = 333 的列,因为它们在 Age 中具有相同的值。有人有什么建议吗?

【问题讨论】:

  • 我很困惑。您如何达到所需的输出?通过过滤原始对象或过滤掉重复项的对象?没有ID=33,只有333
  • 您好,如果我不清楚,抱歉。这将是您过滤掉重复项的对象。然后将显示所有不一致的年龄。例如,如果同一 id 和 name 上的年龄是 22、23、22。我希望显示这些行。对不起我的英语。

标签: r duplicates unique


【解决方案1】:

我刚刚调整了你的代码 :)

library(plyr) 

dat1 <- ddply(dat, .(ID, NAME, AGE), nrow) 
dat2 <- merge(dat1, dat, by=c("ID", "NAME", "AGE")) 
dat3 <- dat2[!(!duplicated(dat2[, 1:2], fromLast=T) & !duplicated(dat2[, 1:2])),] 
dat3[dat3$ID %in% dat3[dat3$V1 == 1, 1], 1:3]

输出为:

   ID NAME AGE
1 111 Mark  22
2 111 Mark  22
3 111 Mark  23
4 222 Anne  21
5 222 Anne  22

样本数据:

dat <- data.frame(ID=c(111,222,333,444,555,111,222,333,111), 
                  NAME=c('Mark','Anne','Chery','Megan','Charles','Mark','Anne','Chery','Mark'), 
                  AGE=c(22,21,30,16,37,23,22,30,22)) 
#   ID    NAME AGE
#1 111    Mark  22
#2 222    Anne  21
#3 333   Chery  30
#4 444   Megan  16
#5 555 Charles  37
#6 111    Mark  23
#7 222    Anne  22
#8 333   Chery  30
#9 111    Mark  22


更新:更正格式以便更好地阅读

【讨论】:

  • 谢谢你!当我添加另一行时遇到一些问题。 (ID=c(111,222,333,444,555,111,222,333,111), NAME=c('Mark','Anne','Chery','Megan','Charles','Mark','Anne','Chery','Mark'), AGE =c(22,21,30,16,37,23,22,30,22))。它将取出两个 111 的 id,因为年龄为 22、23、22。只剩下其中一个,我希望他们都被包括在内,因为他们没有一致的年龄。抱歉,我刚接触 R。非常感谢所有帮助
  • dat1 &lt;- unique(dat[!(!duplicated(dat[,1:2], fromLast=T) &amp; !duplicated(dat[,1:2])),]); dat1[!(!duplicated(dat1[,1]) &amp; !duplicated(dat1[,1], fromLast = T)),]
  • 试过了,但只有 2 个 111 的 id 出现。我打算展示三个 111,因为它们不一致。对不起,如果我不清楚。感谢您的帮助。身份证 |姓名 | 111岁|标记| 22 222|安妮| 21 111|标记| 23 222|安妮| 22 111|标记| 22
  • 有点冗长的溶胶,但它应该可以解决您的要求dat &lt;- data.frame(ID=c(111,222,333,444,555,111,222,333,111), NAME=c('Mark','Anne','Chery','Megan','Charles','Mark','Anne','Chery','Mark'), AGE=c(22,21,30,16,37,23,22,30,22)); library(plyr); dat1 &lt;- ddply(dat,.(ID,NAME, AGE),nrow); dat2 &lt;- merge(dat1,dat,by=c("ID","NAME","AGE")); dat3 &lt;- dat2[!(!duplicated(dat2[,1:2], fromLast=T) &amp; !duplicated(dat2[,1:2])),]; dat3[dat3$ID %in% dat3[dat3$V1==1,1],1:3]。我会要求您更新您的原始问题,以便我可以将其添加到答案中。谢谢!
【解决方案2】:

dplyr 解决方案:

library(dplyr)
dat %>%
    group_by(ID, NAME) %>%
    filter(n() > 1, sum(duplicated(AGE)) == 0) %>%
    ungroup()
# A tibble: 4 x 3
     ID   NAME   AGE
  <dbl> <fctr> <dbl>
1   111   Mark    22
2   222   Anne    21
3   111   Mark    23
4   222   Anne    22

我使用了@Prem 提供的数据。

【讨论】:

    【解决方案3】:

    这是data.table的选项

    library(data.table)
    setDT(dat)[, .SD[.N >1 & !sum(duplicated(AGE))], by = .(ID, NAME)]
    #    ID NAME AGE
    #1: 111 Mark  22
    #2: 111 Mark  23
    #3: 222 Anne  21
    #4: 222 Anne  22
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 2013-07-27
      相关资源
      最近更新 更多