首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据清洗功能:用中位功率替换10的幂。

数据清洗功能:用中位功率替换10的幂。
EN

Stack Overflow用户
提问于 2019-11-12 08:57:17
回答 2查看 95关注 0票数 0

在林业中,手持测量装置经常因处理错误而产生十进制误差.如果在输入数据时不进行校正,就会产生明显的误差,例如一棵树的高度: 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,“领导者或类似的人有不正确的维度数,我做错了什么?”

测试向量

代码语言:javascript
复制
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)

创建幅值滤波器

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2019-11-12 09:34:08

我可以提出一种不同的方法吗?

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2019-11-12 09:35:21

使用strsplit(),您可以获取指数的中位数,并将其粘贴回一起。

代码语言:javascript
复制
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 240
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58815131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档