Получить уникальные записи, если условие выполняется в R data.table - PullRequest
1 голос
/ 09 апреля 2020

Проблема: Предположим, у меня есть объект data.table ниже. Я хочу сохранить только записи, которые удовлетворяют следующему условию:

  • Для каждого CURRENT_DATE и IID сохраняются только строки с state = final_e, если на эту дату уже есть state = inital_e для этого IID.
  • Для каждого CURRENT_DATE и IID, если есть state = e, это не будет затронуто и останется в данных

Любые предложения, как сделать так, чтобы я получил желаемый объект в результате? Большое спасибо !!

library(data.table)

dt <- data.table(
  CURRENT_DATE = c("2020-01-01", "2020-01-01", "2020-01-01", "2020-01-02", "2020-01-02", "2020-01-02"),
  IID = c(1, 1, 2, 1, 2, 2),
  state = c("init_e", "final_e", "e", "e", "init_e", "final_e"),
  vals = c(10, 20, 30, 22, 9, 7),
  text = c("some_text1", "some_text2", "some_text3", "some_text4", "some_text5", "some_text6")
)

## Output:
   CURRENT_DATE IID   state vals       text
1:   2020-01-01   1  init_e   10 some_text1
2:   2020-01-01   1 final_e   20 some_text2
3:   2020-01-01   2       e   30 some_text3
4:   2020-01-02   1       e   22 some_text4
5:   2020-01-02   2  init_e    9 some_text5
6:   2020-01-02   2 final_e    7 some_text6

## Desired Output:
  CURRENT_DATE IID   state vals       text
1:   2020-01-01   1 final_e   20 some_text2
2:   2020-01-01   2       e   30 some_text3
3:   2020-01-02   1       e   22 some_text4
4:   2020-01-02   2 final_e    7 some_text6

РЕДАКТИРОВАТЬ:

library(data.table)

dt2 <- data.table(
  CURRENT_DATE = c("2020-01-01", "2020-01-01", "2020-01-01", "2020-01-02", "2020-01-02"),
  IID = c(1, 1, 2, 1, 2),
  state = c("init_e", "final_e", "e", "e", "final_e"),
  vals = c(10, 20, 30, 22, 7),
  text = c("some_text1", "some_text2", "some_text3", "some_text4", "some_text5")
)

## Output:
   CURRENT_DATE IID   state vals       text
1:   2020-01-01   1  init_e   10 some_text1
2:   2020-01-01   1 final_e   20 some_text2
3:   2020-01-01   2       e   30 some_text3
4:   2020-01-02   1       e   22 some_text4
5:   2020-01-02   2 final_e    7 some_text5

Использование этих данных и один из ответов приводит к

setorder(dt2[, rn := .I], CURRENT_DATE, IID, state)
dt2[sort(c(dt2[state=="e", which=TRUE],
          unique(dt2[state %chin% c("final_e","init_e")], by=c("CURRENT_DATE","IID"))$rn))]

## Output:
   CURRENT_DATE IID   state vals       text rn
1:   2020-01-01   1  init_e   10 some_text1  1
2:   2020-01-01   2       e   30 some_text3  3
3:   2020-01-02   1       e   22 some_text4  4
4:   2020-01-02   2 final_e    7 some_text5  5

## Desired Output:
   CURRENT_DATE IID   state vals       text
1:   2020-01-01   1 final_e   20 some_text2
3:   2020-01-01   2       e   30 some_text3
4:   2020-01-02   1       e   22 some_text4
5:   2020-01-02   2 final_e    7 some_text5

Ответы [ 3 ]

2 голосов
/ 09 апреля 2020

Вот еще один вариант:

setkey(dt, CURRENT_DATE, IID, state)[, rn := .I]
dt[sort(c(dt[state=="e", which=TRUE],
    unique(dt[state %chin% c("final_e","init_e")], by=c("CURRENT_DATE","IID"))$rn))]

Или просто на основе небольшого выборочного набора данных:

dt[state!="init_e"]
0 голосов
/ 22 апреля 2020

Позвольте мне также дать ответ на мой собственный вопрос, поскольку я нашел довольно (очевидное) решение:

  • по сути, я сначала сортирую объект data.table, а затем беру все уникальные элементы ( CURRENT_DATE, IID) поверх него
  • «хитрость» заключается в кодировании переменной state в виде упорядоченного коэффициента
dt2[, state := factor(state, levels = c("final_e", "init_e", "e"),
                      ordered = TRUE)]

sorted_frame <- dt2[order(CURRENT_DATE, IID, state)]
u_frame <- unique(sorted_frame, by = c("CURRENT_DATE", "IID"))
0 голосов
/ 09 апреля 2020

Мы могли бы написать пользовательскую функцию:

check_condition <- function(state) {
     if (any(state == "init_e")) which(state == 'final_e')
     else if(state == 'e') which(state == 'e')
}

и применить ее для каждой группы.

library(data.table)
dt[, .SD[check_condition(state)], .(CURRENT_DATE, IID)]

#   CURRENT_DATE IID   state vals       text
#1:   2020-01-01   1 final_e   20 some_text2
#2:   2020-01-01   2       e   30 some_text3
#3:   2020-01-02   1       e   22 some_text4
#4:   2020-01-02   2 final_e    7 some_text6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...