3

例如,如果我有这些数据:

ID  Value   
1   2
1   2
1   3
1   4
1   10
2   9
2   9
2   12
2   13

我的目标是找到每个 ID 子集的最小值,并且我希望该数字位于 ID 组的第一行,而其他行留空,例如:

ID  Value   Start
1   2       2
1   2       
1   3       
1   4       
1   10      
2   9       9
2   9       
2   12      
2   13      

我的第一直觉是使用为 ID 创建索引

A <- transform(A, INDEX=ave(ID, ID, FUN=seq_along)) ## A being the name of my data

由于我是菜鸟,所以我被困在这一点上。对于每个 ID=n,我想找到该 ID 子集的 min(A$Value),并将其放入 ID=n 和 INDEX=1 的单元格匹配条件中。

任何帮助深表感谢!很抱歉我一直在问问题:(

4

4 回答 4

3

这是一个解决方案:

within(A, INDEX <- "is.na<-"(ave(Value, ID, FUN = min), c(FALSE, !diff(ID))))

  ID Value INDEX
1  1     2     2
2  1     2    NA
3  1     3    NA
4  1     4    NA
5  1    10    NA
6  2     9     9
7  2     9    NA
8  2    12    NA
9  2    13    NA

更新:

这个怎么运作?该命令ave(Value, ID, FUN = min)将函数应用于 的min每个子集Value的值ID。例如,它返回一个由五次2和四次组成的向量9。由于每个子集中除第一个之外的所有值都应为NA,因此该函数"is.na<-"将替换由 定义的逻辑索引处的所有值c(FALSE, !diff(ID))。这个索引是TRUE如果一个值与前一个值相同。

于 2013-02-13T12:20:00.497 回答
2

您快到了。我们只需要创建一个自定义函数来代替seq_alongand 来分割(而不是valueby )。IDIDID

first_min <- function(x){
  nas <- rep(NA, length(x))
  nas[which.min(x)] <- min(x, na.rm=TRUE)
  nas
}

此函数生成一个 NA 向量,并将第一个元素替换为 的最小值Value

transform(dat, INDEX=ave(Value, ID, FUN=first_min)) 

##   ID Value INDEX
## 1  1     2     2
## 2  1     2    NA
## 3  1     3    NA
## 4  1     4    NA
## 5  1    10    NA
## 6  2     9     9
## 7  2     9    NA
## 8  2    12    NA
## 9  2    13    NA
于 2013-02-13T12:23:47.667 回答
1

您可以使用 tapply one-liner 来实现这一点

df$Start<-as.vector(unlist(tapply(df$Value,df$ID,FUN = function(x){ return (c(min(x),rep("",length(x)-1)))})))
于 2013-02-13T12:30:09.627 回答
0

我一直回到这个问题,上面的答案对我帮助很大。初学者也有一个基本的解决方案:

A$Start<-NA A[!duplicated(A$ID),]$Start<-A[!duplicated(A$ID),]$Value

谢谢。

于 2017-11-20T16:03:46.667 回答