在林业中,手持测量装置经常因处理错误而产生十进制误差.如果在输入数据时不进行校正,就会产生明显的误差,例如一棵树的高度: 24厘米、250厘米、26厘米。
我的想法是编写一个过滤函数,将高度转换为科学表示法,忽略NA,如果该值在前一值和后续值的范围内;如果没有,则用与其他值匹配的合适的指数10(即安全的中值==模式)替换该指数。2.4e+1,2.5e+2,2.6e+1 -> 2.4e+1,2.5e+1,2.6e+1.
我很快意识到,一个正常的if/else函数没有很好的响应,因为它不是矢量化的,这就是为什么我使用了Vectorize()而不是编写一个嵌套的ifelse。
到目前为止,这就是我所得到的:
我拿一个测试向量,把它转换成科学的符号,分割速记值,创建引线和滞后变量。复制的函数会找到模式。
由于科学符号是一个字符,在运行语句和检查它是否在范围内之前,我会将其转换为数字。如果不是,我用模式指数代替指数。
当我运行这个函数时,我仍然会遇到很多错误,最值得注意的是,我的Vectorscientifici,“领导者或类似的人有不正确的维度数,我做错了什么?”
测试向量
Vector <- c(2e+2, 2.1e+2, 2.2e+2, 2.3e+4, 2.4e+2)我的预期输出是: c(2e+2,2.1e+2,2.2e+2,2.3e+2,2.4e+2)
创建幅值滤波器
magnitudefilter <- function(Vector){
Vectorscientific <- data.frame(Vectorscientific=formatC(Vector, format = "e"))
Vectorscientific$leader <- dplyr::lead(Vectorscientific$Vectorscientific,1)
Vectorscientific$lagger <- dplyr::lag(Vectorscientific$Vectorscientific,1)
Vectorscientific$shorthandvalue <- gsub("e.*","",Vectorscientific$Vectorscientific)
medianexponent <- median(as.numeric(gsub("^.*e","",Vectorscientific$Vectorscientific)))
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
modeexponent <- getmode(as.numeric(gsub("^.*e","",Vectorscientific$Vectorscientific)))
Vectorscientific$Vectorscientific <- as.numeric(as.character(Vectorscientific$Vectorscientific))
##Create sorting chain
#if lead NA
sortingchain <- function(Vectorscientific){
if(is.na(Vectorscientific[i,"leader"])){
Vectorscientific[i,"Vectorscientific"] <- Vectorscientific[i,"Vectorscientific"]
}
#if lag NA
else if(is.na(Vectorscientific[i,"lagger"])){
Vectorscientific[i,"Vectorscientific"] <- Vectorscientific[i,"Vectorscientific"]
}
# if in range
else if(Vectorscientific[i,"Vectorscientific"] >= Vectorscientific[i,"lagger"] &
Vectorscientific[i,"Vectorscientific"] <= Vectorscientific[i,"leader"]){
Vectorscientific[i,"Vectorscientific"] <- Vectorscientific[i,"Vectorscientific"]
}
#if replace exponent
else {
Vectorscientific[i,"Vectorscientific"] <- paste0(Vectorscientific[i,"shorthandvalue"], "e+",medianexponent)
}
}
#Vectorize sorting chain (if/else not vectorised in R)
vectorizedsort <- Vectorize(sortingchain)
if(identical(modeexponent, medianexponent)){
for(i in Vectorscientific){
vectorizedsort(Vectorscientific[i,])
}
}
return(Vectorscientific$Vectorscientific)
}
magnitudefilter(Vector)发布于 2019-11-12 09:34:08
我可以提出一种不同的方法吗?
Vector <- c(2e+2, 2.1e+2, 2.2e+2, 2.3e+4, 2.4e+2)
plot(Vector)
library(robustbase)
#you could adjust the model, e.g., to be quadratic if necessary
fit <- lmrob(log(Vector) ~ x, data = data.frame(Vector, x = seq_along(Vector)), setting="KS2014")
#outliers are values with robust weight == 0
#you could use a different threshold, e.g., < 0.1
out <- !(fit$rweights)
result <- Vector
result[out] <- result[out] / round(result[out]/median(result[!out]), -2)
#[1] 200 210 220 230 240发布于 2019-11-12 09:35:21
使用strsplit(),您可以获取指数的中位数,并将其粘贴回一起。
v <- c(2e+2, 2.1e+2, 2.2e+2, 2.3e+4, 2.4e+2)
s <- strsplit(formatC(v, format="e"), "\\+")
md <- median(as.numeric(mapply(`[`, s, 2)))
as.numeric(paste0(mapply(`[`, s, 1), "+", md))
# [1] 200 210 220 230 240https://stackoverflow.com/questions/58815131
复制相似问题