【问题标题】:Subsetting by multiple aggregate conditions in dplyr通过 dplyr 中的多个聚合条件进行子集化
【发布时间】:2016-04-23 07:36:56
【问题描述】:

我希望有人知道 dplyr 中的一种简单/高效的方法,我可以在其中定义一个指标变量,如果在日期 X 上,IP 地址出现 >50 次,则取值为 1。数据是两列,一列是 IP 地址,另一列是相关的访问日期。

例如,我希望机器人列中的以下输出(假设日期/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

谢谢!

【问题讨论】:

  • 请展示一个可重现的小例子
  • @akrun,包括在上面!谢谢!

标签: r aggregate dplyr indicator dummy-variable


【解决方案1】:

您可以group_by 这两个变量并使用n() 来测试当天有多少地址。

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

【讨论】:

  • 这里不需要ifesle,只需group_by(df, IP, Date) %>% mutate(keep = as.numeric(n() > 2))即可。
【解决方案2】:

为了效率,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)]

当然,当你想要 50 作为阈值时,你需要将条件更改为.N &gt;= 50

【讨论】:

    【解决方案3】:

    我们可以使用data.table。将“data.frame”转换为“data.table”(setDT(df1)),按“IP”和“日期”分组,我们通过将逻辑(.N&gt;=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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2020-01-07
      • 1970-01-01
      • 2017-08-03
      • 1970-01-01
      • 2011-03-04
      相关资源
      最近更新 更多