0

我有这样的数据设置:

date     ID   weight    
Apr 4    1    21
Apr 5    1    22
Apr 6    1    23
Apr 4    2    30
Apr 5    2    31
Apr 6    2    32
Apr 7    2    12

我想进入并找出最后记录的重量不是该 ID 的最大值的情况。因此,在上面的示例中,最后一行是该 ID 的最高日期,ID=2但不是最高权重。

我可以设置一个 for 循环,它基本上会吐出一个数据框,其中包含最大日期的权重和 ID 内的最大权重,我可以做一个不同的分数。差值大于 0 的任何人都需要删除最后日期的行。

subs <- levels(as.factor(df$ID)) 
newdf <- as.data.frame(rep(subs, each = 1))
names(newdf) <- c('ID')
newdf$max <- NA
newdf$last <- NA

for (i in subs){
  subdata = subset(df, ID == i)
  lastweight <- subdata$Weight[length(subdata$ID)]
  maxweight <- max(subdata$Weight)
  newdf$max[IDdate$ID == i]<-maxweight
  newdf$last[IDdate$ID == i]<-lastweight
}

IDdate$diff <- as.numeric(IDdate$max) - as.numeric(IDdate$last)

现在我正在努力做的是想出一个解决方案,让我可以将 ID 放在哪里diff>0并进入原始数据框并删除这些 ID 的最后日期。

我试过了whichsubset但这不是我想要的。

4

2 回答 2

1

我喜欢分两步解决这些问题。首先,编写一个函数,在单个组上执行我想要的操作(假设您的数据按日期排序):

df2 <- df[df$ID == 2,]

myfun <- function(x) {
  # if the maximum weight value isn't found on the last row,
  if (which.max(x$weight) != nrow(x)) { 
    # return the data.frame without the last row:
    return (x[-nrow(x), ])
  } else {
    # otherwise, return the whole thing:
    return (x) 
  }
}

myfun(df2)

然后您可以在任意数量的“split-apply-combine”包中使用该功能:

plyr

library(plyr)
ddply(df, .(ID), myfun)

数据表

library(data.table)
DT <- data.table(df)
DT[, myfun(.SD), by=ID]
于 2013-09-20T20:15:31.063 回答
0

您可以使用此过滤器:

DF[as.logical(with(DF, ave(weight, ID, FUN=function(x)
    ifelse(seq_along(x)==length(x), x<max(x), TRUE)))),]

如果它的权重不是组的最大值,它将删除最后一行(按 ID 分组)。

于 2013-09-20T20:19:58.993 回答