如何获得新近度值?

时间:2014-07-20 04:56:10

标签: r datetime database-design

我想获得最近的价值。

 ID month_0   month_01 month_02 month_03 
 1        0         10        0        0
 2       10          0        0        0
 3       10          0       35        0
 4        0          0       15        0
 5        0          0        0       35

我的数据如上, 我想获得新近度值。

recency
id 1 -> 1
id 2 -> 0
id 3 -> 0
id 4 -> 2
id 5 -> 3

请帮助我如何获得新近度值。

3 个答案:

答案 0 :(得分:4)

df <- data.frame(month0 = c(0,10,10,0,0), month1 = c(10,0,0,0,0), month2 = c(0,0,35,15,0), month3 = c(0,0,0,0,35))

apply(df, 1, function(x) Position(function(y) y > 0, x)) - 1
# [1] 1 0 0 2 3

答案 1 :(得分:4)

这是一种方式。不确定是否采用标准方式,但这使用rle(运行长度编码),这似乎是这个问题的逻辑。

假设dat是您的数据

> apply(dat[-1], 1, function(x){ 
      with(rle(x), ifelse(!values[1], lengths[1], 0)) })
# [1] 1 0 0 2 3

答案 2 :(得分:0)

你可以尝试:

 dat <- structure(list(ID = 1:5, month_0 = c(0L, 10L, 10L, 0L, 0L), month_01 = c(10L, 
 0L, 0L, 0L, 0L), month_02 = c(0L, 0L, 35L, 15L, 0L), month_03 = c(0L, 
 0L, 0L, 0L, 35L)), .Names = c("ID", "month_0", "month_01", "month_02", 
 "month_03"), class = "data.frame", row.names = c(NA, -5L))

通过首先在montht(!!dat[,-1])中创建值> 0的逻辑横向矩阵并将其与dat [, - 1]

的列号相乘来创建索引
 indx <- t((!!dat[,-1]))*seq_len(ncol(dat[,-1]))

如果我理解正确,您需要每个ID的第一个非零值。 ID3在month_0month_02中的值> 0。因此,请选择month_0

创建行列索引,并按duplicated

仅选择每列的第一个值
 indx1 <- which(!!indx,arr.ind=T)
 indx[indx1[!duplicated(indx1[,2]),]]-1
 #[1] 1 0 0 2 3

速度比较

  set.seed(148)
  m1 <- matrix(sample(c(0, 10,25,35,15),1e5*10,replace=T),nrow=1e5)
  d1 <- data.frame(ID=1:1e5, m1)

 f1 <- function(dat) {
 indx <- t(!!dat[,-1])*seq_len(ncol(dat[,-1]))
 indx1 <- which(!!indx, arr.ind=T)
 indx[indx1[!duplicated(indx1[,2]),]]-1
 }

f2 <- function(dat){
apply(dat[-1], 1, function(x){ 
with(rle(x), ifelse(!values[1], lengths[1], 0)) })
 }

 f3 <- function(dat){
 apply(dat[-1], 1, function(x) Position(function(y) y > 0, x)) - 1
 }

system.time(r1 <- f1(d1))
#   user  system elapsed 
#  0.550   0.004   0.555 

system.time(r2 <- f2(d1))
#   user  system elapsed 
#  7.870   0.000   7.851

system.time(r3 <- f3(d1))
#   user  system elapsed 
#  0.531   0.000   0.530 

identical(r1,r3)
#[1] TRUE
identical(r1,r2)
#[1] TRUE