Как удалить дубликаты, но сохранить самые последние данные в R

r dataframe merge

74 просмотра

4 ответа

47 Репутация автора

У меня есть следующие два кадра данных:

df1 = data.frame(names=c('a','b','c','c','d'),year=c(11,12,13,14,15), Times=c(1,1,3,5,6))
df2 = data.frame(names=c('a','e','e','c','c','d'),year=c(12,12,13,15,16,16), Times=c(2,2,4,6,7,7))

Я хотел бы знать, как я мог бы объединить вышеупомянутый df, но сохранить только самые последние времена в зависимости от года. Это должно выглядеть так:

Names  Year   Times
a      12     2
b      12     2
c      16     7
d      16     7
e      13     4
Автор: LordVoldemort Источник Размещён: 18.07.2016 09:15

Ответы (4)


5 плюса

223203 Репутация автора

Решение

Я предполагаю, что вы не имеете в виду объединять их, а скорее объединяете их в стек. Ваш вопрос неоднозначен, поскольку «дублирование» может происходить на уровне данных или на уровне векторов. В вашем примере не показано дублирование на уровне данных, но на уровне векторов. Лучший способ описать проблему состоит в том, что вы хотите, чтобы последняя (или максимальная) Timesзапись в каждой группе имела namesзначения:

> df1
  names year Times
1     a   11     1
2     b   12     1
3     c   13     3
4     c   14     5
5     d   15     6
> df2
  names year Times
1     a   12     2
2     e   12     2
3     e   13     4
4     c   15     6
5     c   16     7
6     d   16     7
> dfr <- rbind(df1,df2)
> dfr <-dfr[order(dfr$Times),]
> dfr[!duplicated(dfr, fromLast=TRUE) , ]
   names year Times
1      a   11     1
2      b   12     1
6      a   12     2
7      e   12     2
3      c   13     3
8      e   13     4
4      c   14     5
5      d   15     6
9      c   15     6
10     c   16     7
11     d   16     7

> dfr[!duplicated(dfr$names, fromLast=TRUE) , ]
   names year Times
2      b   12     1
6      a   12     2
8      e   13     4
10     c   16     7
11     d   16     7
Автор: 42- Размещён: 18.07.2016 09:26

4 плюса

31407 Репутация автора

Это использует базовые функции R; Есть также более новые пакеты (например, plyr), которые, по мнению многих, делают процесс split-apply-comb более интуитивным.

df <- rbind(df1,  df2)
do.call(rbind, lapply(split(df, df$names), function(x) x[which.max(x$year), ]))

##   names year Times
## a     a   12     2
## b     b   12     1
## c     c   16     7
## d     d   16     7
## e     e   13     4
Автор: Aaron - Reinstate Monica Размещён: 18.07.2016 09:27

3 плюса

9498 Репутация автора

Мы также могли бы использовать aggregate:

df <- rbind(df1,df2)
aggregate(cbind(df$year,df$Times)~df$names,df,max)

  # df$names V1 V2
# 1        a 12  2
# 2        b 12  1
# 3        c 16  7
# 4        d 16  7
# 5        e 13  4
Автор: 989 Размещён: 18.07.2016 10:12

1 плюс

33362 Репутация автора

Если вы хотите увидеть data.tableрешение,

# load library
library(data.table)
# bind by row and convert to data.table (by reference)
df <- setDT(rbind(df1, df2))
# get the result
df[order(names, year), .SD[.N], by=.(names)]

Вывод следующий:

   names year Times
1:     a   12     2
2:     b   12     1
3:     c   16     7
4:     d   16     7
5:     e   13     4

Последняя строка упорядочивает данные с привязкой к строке по именам и годам, а затем выбирает последнее наблюдение ( .sd[.N]) для каждого имени.

Автор: lmo Размещён: 19.07.2016 12:45
Вопросы из категории :
32x32