如何在 R 中从数据帧 * 不重复 * 中对均匀间隔的样本进行子集化?

How to subset evenly spaced samples from a dataframe *without duplicates* in R?

我正在尝试在 R 中创建更大数据集的均匀间隔(时间或深度)子集。我的原始数据不是均匀间隔的。

以下是需要改进的功能:

# calculate step size and subsets df accordingly
spacedSS <- function(df, n, var){
    stp <- (max(var)-min(var))/(n - 1)       #calculate step size
    stps <- min(var)+0:(n-1)*stp             #calculate step values
    res <- lookupDepth(df, stps, var)
    return(as.data.frame(res))
}

# finds values in var closest to stps, returns subsetted df
lookupDepth <- function(df, stps, var){ 
    indxs <- rep(0, times=length(stps)) # create empty index vector
    for(i in seq_along(stps)) {         # for every subsample row
                                        # find the one closest to the step value
                                        # TODO: only if it isn't already in the df
        indxs[i] <- which.min((var - stps[i])^2)
    }
    sampls <- df[indxs, ]               #subset by these new indexes
    return(as.data.frame(sampls))
}

这里将它们应用于类似于我自己的数据来说明问题:

# generate data  
depth <- c(seq(650, 750, length.out = 50), seq(750, 760, length.out = 3),
           seq(760, 780, length.out = 5), seq(780, 800, length.out = 20))
age   <- c(seq(40,  41,  length.out = 50), seq(41,  42,  length.out = 3),
           seq(42,  47,  length.out = 5), seq(47,  48,  length.out = 20))
id    <- seq_along(age)
dat   <- data.frame(id, depth, age)

# subset 10 samples of dat evenly spaced in depth/age
ss.depth <- spacedSS(dat, 10, dat$depth)
ss.age   <- spacedSS(dat, 10, dat$age)

这是数据图:

# plot it using my depthplotter function
source("https://raw.githubusercontent.com/japhir/DepthPlotter/master/DepthPlotter.R")
DepthPlotter(dat[, c("depth", "age")], xlab = "Age (Ma)")
segments(30, ss.depth$depth, ss.depth$age, col = "blue")
segments(ss.age$age, 640, y1 = ss.age$depth, col = "red")

所以我要解决的问题是子集函数目前没有查看已经使用的索引:

# the problem I'm trying to solve:
length(unique(ss.age$id)) != length(unique(ss.depth$id))
TRUE
# it picked the same samples sometimes because they were the closest ones!
ss.age$id
[1]  1 45 53 55 55 56 57 57 61 78

所以正如你所看到的,问题是当它进行子集化时,它目前没有考虑到已经选择的样本。知道如何解决这个问题吗?

所以我最后请了一个朋友帮助我,我们构建了一个相当复杂的 Simulated Annealing 方法。

基本上我们创建了一个函数来查看是否有任何重复的索引值,如果有,则非常简单地修复它们。然后变异函数随机改变索引值。对照原始数据集检查这个新子集的丢失,如果它们比之前的选择更好,则生成并选择随机突变。选择标准起初相当宽松,但随着时间的推移变得更加严格,从而产生了一个非常酷的优化数据子集!

如果您对我们使用的代码感兴趣,请在下方发表评论,我们会把它放在某个地方。