R-通过索引列表通过公差进行组数据



我不知道如何尽快解释。我尽力了:我有以下示例数据:

Data<-data.frame(A=c(1,2,3,5,8,9,10),B=c(5.3,9.2,5,8,10,9.5,4),C=c(1:7))

和索引

Ind<-data.frame(I=c(5,6,2,4,1,3,7))

Ind中的值对应于Data中的C列。现在,我想从第一个Ind值开始,然后在data data.frame(列C(中找到相应的行。从该行中,我想上下找到1列的A列中的值1。我想将这些值写入Result dataFrame添加组ID列并将其删除在dataframe Data(其中i,其中i找到他们(。然后,我从索引dataframe Ind中的下一个条目开始,然后直到data.frame.frame Data为空。我知道如何将我的Ind与我的DataC匹配,以及如何在for循环中删除和删除其他内容,但我不知道要点,这是我的问题:

当我在Data中找到我的行时,如何在该条目上和下方的公差范围内查找A的拟合值以获取我的Group ID?

我要得到的是这个结果:

A     B     C     Group
1     5.3   1      2               
2     9.2   2      2                 
3     5     3      2             
5     8     4      3          
8     10    5      1                 
9     9.5   6      1                
10    4     7      4

也许有人可以帮助我解决问题的关键点,甚至可以以快速的方式解决这个问题。

非常感谢!

通常:避免在循环中删除或通过行删除或生长数据框架。R的内存管理意味着每次添加或删除一行时,都会制作另一个数据框架的副本。垃圾收集最终将丢弃数据框架的"旧"副本,但是垃圾可以迅速积累并降低性能。相反,将逻辑列添加到Data数据框架中,然后将"提取"行设置为TRUE。如此这样:

Data$extracted <- rep(FALSE,nrow(Data))

关于您的问题:我得到了一组不同的分组数字,但是组相同。

可能会有一种更优雅的方法来做到这一点,但这将完成。

# store results in a separate list
res <- list()
group.counter <- 1
# loop until they're all done.
for(idx in Ind$I) {
  # skip this iteration if idx is NA.
  if(is.na(idx)) {
    next
  }
  # dat.rows is a logical vector which shows the rows where 
  # "A" meets the tolerance requirement.
  # specify the tolerance here.
  mytol <- 1
  # the next only works for integer compare.
  # also not covered: what if multiple values of C 
  # match idx? do we loop over each corresponding value of A, 
  # i.e. loop over each value of 'target'?
  target <- Data$A[Data$C == idx]
  # use the magic of vectorized logical compare.
  dat.rows <- 
    ( (Data$A - target) >= -mytol) & 
    ( (Data$A - target) <= mytol) & 
    ( ! Data$extracted)
  # if dat.rows is all false, then nothing met the criteria.
  # skip the rest of the loop
  if( ! any(dat.rows)) {
    next
  }
  # copy the rows to the result list.
  res[[length(res) + 1]] <- data.frame(
    A=Data[dat.rows,"A"],
    B=Data[dat.rows,"B"],
    C=Data[dat.rows,"C"],
    Group=group.counter # this value will be recycled to match length of A, B, C.
  )
  # flag the extraction.
  Data$extracted[dat.rows] <- TRUE
  # increment the group counter
  group.counter <- group.counter + 1
}
# now make a data.frame from the results.
# this is the last step in how we avoid 
#"growing" a data.frame inside a loop.
resData <- do.call(rbind, res)

相关内容

最新更新