Вот возможное решение, но сначала нам нужно сгенерировать некоторые данные, которые представляют вашу проблему.Что хорошо в вашем сценарии, так это то, что ложные точки данных представляют собой большие всплески, которые довольно очевидны даже визуально.
Генерация данных
set.seed(15161)
x <- seq(pi/10,10*pi,by=pi/100)
y <- sin(x) # using sin() generates some osciliating data
z <- sample(c(0,-5),length(y),
prob=c(0.99,0.01),replace=TRUE) # pepper the data with random spikes
y <- y + z
df <- data.frame(cbind(x,y,z))
length(which(df$z==-5)) # the number of spikes ~ 13
plot(df$x,df$y,type="l",ylim=c(-10,2),col="blue",xlab="x",ylab="y")
abline(h=0,lty=5)
Удаление ложных измерений (очистка данных)
В предоставленных вами данных ложные данные очень велики по сравнению с фоном хороших измерений.То есть ваши измерения движутся медленно, постепенно увеличиваясь или уменьшаясь, затем подбросьте прыжок / падение на> 20 единиц.Поэтому я написал функцию, которая будет определять и удалять любые точки данных, которые представляют увеличение / уменьшение выше некоторого порогового значения (в вашем случае ~ 20 единиц, в моем рабочем примере выше ~ 2 единиц должно быть достаточно).
Код функцииis:
f <- function(df,clean,threshold){
y <- df[,clean]
for(i in 1:length(y)){
if(is.na(y[i]) | is.na(y[i+1])){
next
}
if(abs(y[i+1]-y[i])>threshold){
y[i+1] <- NA
}
}
return(df[!is.na(y),])
}
cleaned.df <- f(df,clean="y",threshold=2) # Run the function to clean the data
length(which(cleaned.df$z==-5)) # number of spikes in cleaned data is now 0
График очищенных результатов
plot(cleaned.df$x,cleaned.df$y,type="l",ylim=c(-10,2),col="blue",xlab="x",ylab="y")
abline(h=0,lty=5)
Примечания и предостережения
- Убедитесь, что ваши данные последовательно упорядочены перед запуском функции (т. Е. Хронологически отсортированные измерения)
- Я рекомендую вам выбрать порог около 20 единиц (только визуальный осмотр вашего графика кажется достаточным.
- Функция очистки может быть неэффективной при удалении 2 или более последовательных всплесков. Однако вы можете запускать данные через функцию очистки несколько раз, и это должно работать.
- Мы можем разработать более строгие подходы, но я подумал, что это решение будет простым и эффективным. Дайте нам знать, если у вас все еще есть проблемы, и мы можем разработать большестрогие решения.
Редактировать 1:
Я только что увидел, что вы загрузили некоторые реальные данные.Немного подправили функцию, чтобы приспособить шипы, которые меняют знак измерений.Вот результаты, относящиеся к вашим данным, которые, как мне кажется, работают.
df <- read.csv("figure1data.csv")
plot(df$X,df$three,type="l",col="blue",xlab="x",ylab="y",ylim=c(-150,50))
abline(h=0,lty=5)
cleaned.df1 <- f(df,clean="three",threshold=20)
plot(cleaned.df1$X,cleaned.df1$three,type="l",col="blue",xlab="x",ylab="y",
ylim=c(-150,50))
abline(h=0,lty=5)
Редактировать 2: Ответ на комментарии OP
Чтобы удалить случаи, когда возникают последовательные всплески, просто перезапустите функцию на очищенных данных.
cleaned.df2 <- f(cleaned.df1,clean="three",threshold=20)
Чтобы восстановить все строки в данных и преобразовать «три» точки переменных с шипами в NA
, просто объедините данные обратно следующим образом.
New.df <- merge(df[,colnames(df)!="three"],
cleaned.df2[,colnames(df) %in% c("X","three")],
by="X",all.x=TRUE)
Чтобы убедиться, что все работает должным образом
df[which(!complete.cases(New.df)),]
New.df[which(!complete.cases(New.df)),]
вы ясно видите, что строки с переменными "тремя" шипами теперь находятся в NA
в New.df