代码之家  ›  专栏  ›  技术社区  ›  Matt Bannert

随时间变化的条件计数?

  •  3
  • Matt Bannert  · 技术社区  · 14 年前

    Id想计算二进制因子变量的更改次数。对于每个用户id,此变量可以不时地来回更改多次。现在id想计算在给定时间范围内每个用户id对此变量的更改数。

    数据按id、year、month、myfactor排序。我在MySQL中尝试过,但至今没有成功。

    提前给你建议。。。

    嗯,当然。。。以下是一个很抱歉没有立即提供的例子,我的头很痛;):


       myf   Year    month userid   
      1 A    2005       1    260           
      2 B    2005       2    260           
      3 B    2005       4    260           
      4 A    2005       5    260           
      5 B    2005       6    260           
      6 B    2005       1    261 
    

    如果这是我的数据集,我想更新changes列,计算每个用户myf的更改数。基本上我想结束的是:

      user  changes
       260     3
       260     0
    

    等等。。。

    高温高压

    3 回复  |  直到 14 年前
        1
  •  4
  •   Richie Cotton Joris Meys    14 年前
    #Some data
    dfr <- data.frame(
       binary_variable = runif(100) < .7,
       id = sample(7, 100, replace = TRUE)
    )
    
    #Split by id
    split_by_id <- with(dfr, split(binary_variable, id))
    
    #Number of changes
    sapply(split_by_id, function(x) sum(diff(x) != 0))
    
        2
  •  5
  •   Joris Meys    14 年前

    另一个编辑:

    考虑到你对其他解决方案的反应,你可以在一行中得到你想要的:

    Data$extra <- ave(as.integer(Data$myf),Data$id,FUN=function(x) sum(diff(x)!=0))
    

    在这种情况下不需要合并。


    rle . 一定要去看看那个。

    基于Joshuas的回答,这个例子向您展示了如何轻松地使用日期来选择给定的时间跨度。

    编辑:我更新了答案,向您展示如何轻松地将您的年和月列转换为日期。你也应该使用 as.numeric

    #Testdata
    set.seed(21)
    Data <- data.frame(id=rep(letters[1:3],each=24),
                       year= rep(rep(c(2005,2006),each=12),6),
                       month=rep(1:12,6),
                       myf=sample(c("A","B"),24*3,TRUE))
    
    #transformation
    Data$dates <- as.Date(paste(Data$year,Data$month,"1",sep="-"))
    #function
    
    cond.count <- function(from,to,data){
        x <- data[data$dates>from & data$dates<to,]
        tapply(as.numeric(x$myf),x$id,function(y)sum(diff(y)!=0))
    }
    
    #example
    from <- as.Date("2005-01-01")
    to <- as.Date("2006-04-15")
    
    cond.count(from,to,Data)
    
        3
  •  2
  •   Joshua Ulrich    14 年前

    这是我的猜测。

    set.seed(21)
    Data <- data.frame(id=sample(letters[1:3],20,TRUE),
                       date=sample(1:3,20,TRUE),
                       myfactor=sample(0:1,20,TRUE))
    Data <- Data[order(Data$id,Data$date),]
    
    DataCh <- aggregate(Data[,"myfactor",FALSE],
                by=Data[,c("id","date")], function(x) sum(diff(x)!=0))
    DataCh <- DataCh[order(DataCh$id,DataCh$date),]
    

    lines <- "   myf   Year    month userid   
     1 A    2005       1    260           
     2 B    2005       2    260           
     3 B    2005       4    260           
     4 A    2005       5    260           
     5 B    2005       6    260           
     6 B    2005       1    261 "
    
    Data <- read.table(con <- textConnection(lines)); close(con)
    
    DataCh <- aggregate(Data[,"myf",FALSE],
                by=Data[,"userid",FALSE], function(x) sum(diff(unclass(x))!=0))
    
    merge(Data,DataCh,by="userid",suffixes=c("",".change"))
    #   userid myf Year month myf.change
    # 1    260   A 2005     1          3
    # 2    260   B 2005     2          3
    # 3    260   B 2005     4          3
    # 4    260   A 2005     5          3
    # 5    260   B 2005     6          3
    # 6    261   B 2005     1          0