如何在 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 方法。
基本上我们创建了一个函数来查看是否有任何重复的索引值,如果有,则非常简单地修复它们。然后变异函数随机改变索引值。对照原始数据集检查这个新子集的丢失,如果它们比之前的选择更好,则生成并选择随机突变。选择标准起初相当宽松,但随着时间的推移变得更加严格,从而产生了一个非常酷的优化数据子集!
如果您对我们使用的代码感兴趣,请在下方发表评论,我们会把它放在某个地方。
我正在尝试在 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 方法。
基本上我们创建了一个函数来查看是否有任何重复的索引值,如果有,则非常简单地修复它们。然后变异函数随机改变索引值。对照原始数据集检查这个新子集的丢失,如果它们比之前的选择更好,则生成并选择随机突变。选择标准起初相当宽松,但随着时间的推移变得更加严格,从而产生了一个非常酷的优化数据子集!
如果您对我们使用的代码感兴趣,请在下方发表评论,我们会把它放在某个地方。