У меня есть датафрейм в r, и я должен выполнить фильтрацию (не просто подсчет или сумму) по группам идентификаторов - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть фрейм данных с 3 полями (ID, Date, alue), и для каждого ID я хочу, чтобы строка имела минимальную дату между всеми строками, у которых дата больше, чем строка с самой большой датой со значением == 0и == 2. Я не знаю, ясно ли это, но я думаю, что с примером ниже это будет.

Точнее, мой фрейм данных выглядит так:

ID       Date     Value
1     19960708      3
1     19960901      2
1     19960916      3
1     19970901      0
1     19971001      3
1     19971231      3
1     19980101      3
2     19900806      3
2     19901215      3
2     19910629      0
2     19911007      3
2     19911201      3
2     19990901      3
2     20001001      3

Я хотел бы иметь в качестве вывода:

ID     Date       Value
1     19971001      3
2     19911007      3

Этот вывод, потому что для идентификатора 1 наибольшая дата со значением == 0 равна 19970901. Поэтому я беру минумин значений больше, чем 19970901.То же самое для идентификатора 2.

Я пытаюсь использовать dplyr для фильтрации данных, но у меня нет вывода, который я хочу.Ниже кода, который я использую:

  df %>% 
    group_by(ID) %>%
    filter(DATE > max(df[VALUE==0 | VALUE==2,]$DATE)) %>%
    filter(DATE == min(DATE))

Вывод этого не тот, который я ожидаю, потому что он работает для первого идентификатора, но затем он использует эту дату для сравнений вдругие идентификаторы.В качестве вывода у меня есть:

ID     Date       Value
1     19971001      3
2     19990901      3

Как я могу это исправить?Спасибо.

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

data.table решение:

fun1 <- function(data, var = "Value", afterMax = c(0,2), findMin = 3) {
    max_id <- max(which(data[[var]] %in% afterMax))
    tmp    <- which(  data[[var]] %in% findMin )
    min_id <- min(tmp[tmp>max_id])
    return(data[min_id,])
}

setDT(df1)[,fun1(.SD),by="ID"]

результат:

#   ID     Date Value
#1:  1 19971001     3
#2:  2 19911007     3

Для решения dplyr используйте

df1 %>% group_by(ID) %>% do(.,fun1(.))
0 голосов
/ 20 сентября 2018

Другой возможный подход с выводом data.table

library(data.table)
setDT(df)

#ensure that df is sorted in ascending by ID and Date
setorder(df, ID, Date)

df[df[, .I[max(which(Value==0 | Value==2)) + 1L], by=.(ID)]$V1]

:

   ID     Date Value
1:  1 19960916     3
2:  2 19911007     3

При вышеуказанном подходе, если есть идентификаторы без 0 или 2, строка со всеми столбцамизаполненные NA появятся для этого идентификатора.Следовательно, если вы хотите увидеть идентификатор для отображения NA для всех других столбцов, кроме столбца ID, вы можете использовать это:

setDT(df1, keep.rownames=TRUE)[, rn := as.integer(rn)]
setorder(df1, ID, Date)
df1[df1[, .(rn=.I[max(which(Value==0 | Value==2)) + 1L]), by=.(ID)], on=.(ID, rn)][, 
    rn := NULL]

output:

   ID     Date Value
1:  1 19971001     3
2:  2 19911007     3
3:  3       NA    NA

data:

df <- read.table(text="ID       Date     Value
1     19960708      3
1     19960901      2
1     19960916      3
1     19970901      0
1     19971001      3
1     19971231      3
1     19980101      3
2     19900806      3
2     19901215      3
2     19910629      0
2     19911007      3
2     19911201      3
2     19990901      3
2     20001001      3", header=TRUE)

df1 <- read.table(text="ID       Date     Value
1     19960708      3
1     19960901      2
1     19960916      3
1     19970901      0
1     19971001      3
1     19971231      3
1     19980101      3
2     19900806      3
2     19901215      3
2     19910629      0
2     19911007      3
2     19911201      3
2     19990901      3
2     20001001      3
3     19990901      3
3     20001001      3", header=TRUE)
0 голосов
/ 20 сентября 2018

Вам не нужно снова указывать df in в первом вызове фильтрации:

library(dplyr)

df %>% 
  group_by(ID) %>%
  filter(Date > max(Date[Value == 0 | Value == 2])) %>%
  filter(Date == min(Date))

# A tibble: 2 x 3
# Groups:   ID [2]
#      ID     Date Value
#   <int>    <int> <int>
# 1     1 19971001     3
# 2     2 19911007     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...