2016-01-18 3 views
0

Я надеялся, что кто-то знает о простой/эффективной в dplyr, в которой я могу определить переменную индикатора, чтобы принять значение 1, если в Date X IP-адрес присутствовал> 50 раз. Данные представляют собой два столбца, один из IP-адресов и другие связанные даты доступа.Подмножество нескольких состояний агрегата в dplyr

В качестве примера я хотел бы получить следующий вывод в столбце Robot (при условии, что комбинация Date/IP была> = 3).

IP Date Robot 
1 A 1 
1 A 1 
1 A 1 
1 B 0 
2 B 0 
2 C 1 
2 C 1 
2 C 1 
3 C 0 
3 D 0 
4 A 0 

Спасибо!

+2

Пожалуйста, покажите небольшой воспроизводимый пример – akrun

+0

@akrun, включенную выше! Благодаря! – ew23

ответ

4

Вы можете указать group_by две переменные и использовать n(), чтобы проверить, сколько адресов существует в тот день.

group_by(df,date,ip) %>% 
    mutate(keep=as.numeric(n() > 50)) 
+2

Здесь вам действительно не нужно 'ifesle', просто' group_by (df, IP, Date)%>% mutate (keep = as.numeric (n()> 2)) 'должен делать. –

0

Для эффективности той же логики в data.table:

library(data.table) 

DT <- fread("IP Date 
      1 A 
      1 A 
      1 A 
      1 B 
      2 B 
      2 C 
      2 C 
      2 C 
      3 C 
      3 D 
      4 A") 

DT[, Robot := ifelse(.N >= 3, 1, 0), keyby = .(IP, Date)] 

Конечно, вы должны изменить условие для .N >= 50 если вы хотите 50 быть порог.

0

Мы могли бы использовать data.table. Преобразуйте 'data.frame' в 'data.table' (setDT(df1)), сгруппированные по «IP» и «Date», мы создаем «Robot», преобразовывая логическое (.N>=3) в двоичное представление. Это можно сделать, просто используя + для логического вектора или используя функцию as.integer.

library(data.table) 
setDT(df1)[, Robot:= +(.N>=3), .(IP, Date)] 

+ можно заменить as.integer


Или с base R, мы можем использовать ave

transform(df1, Robot=as.integer(ave(IP, IP, Date, FUN=length)>=3))