2014-12-13 2 views
1

Я имею данные, как это:R: Возможна ближайшая соседка для не-NA?

v1 = c(-1, 1, 420, 400, 400, 170, 420) 
v2 = c(350, 460, 420, 400, 500, 170, 420) 
v3 = c(350, 460, 420, 1, 500, 3, 1) 
v4 = c(1, NA, 420, 1, NA, 170, 420) 
v5 = c(350, 400, 400, 1, 1, 3, 300) 
v6 = c(350, 400, NA, 500, 500, 170, 300) 
v7 = c(7,400,200,7,500,170,7) 

DF1= data.frame(v1, v2, v3, v4, v5, v6, v7) 

В результате в таблице/DF следующим образом:

v1 v2 v3 v4 v5 v6 v7 
1 -1 350 350 1 350 350 7 
2 1 460 460 NA 400 400 400 
3 420 420 420 420 400 NA 200 
4 400 400 1 1 1 500 7 
5 400 500 500 NA 1 500 500 
6 170 170 3 170 3 170 170 
7 420 420 1 420 300 300 7 

3-значного числа рабочих часов (400 = 40h) и один цифры являются состояниями занятости. Проблема с данными заключается в том, что я нацелен на ежемесячную информацию (v1-v7 - месяцы), но у меня есть рабочее время, проведенное только один раз в год. Поэтому я надел это на штаты, и теперь у меня есть такие же пробелы, которые нужно заполнить.

Я хотел бы заменить состояния «-1», «NA», «1» и «3» на ближайшего соседа (без вычисления, просто замена следующего значения выше «50»), отдавая приоритет значение слева/переменная слева от случая, которая должна быть заменена.

В конце концов, это должно выглядеть:

v1 v2 v3 v4 v5 v6 v7 
1 350 350 350 350 350 350 7 
2 460 460 460 460 400 400 400 
3 420 420 420 420 400 NA 200 
4 400 400 400 400 500 500 7 
5 400 500 500 500 500 500 500 
6 170 170 170 170 170 170 170 
7 420 420 420 420 300 300 7 

Примечание линии 4, где 2 «1», где заменено значением слева и и один со следующим значением выше 50 справа - вот что я имел в виду с «приоритетом слева».

До сих пор у меня только был опыт со случайным прикосновением пакета-примаза, и я видел пакет knn, но, насколько мне известно, он работает только с NA, не так ли?

Я благодарен за любой намек, потому что экспортировать его в формате CSV и решить его вручную бы меня 10+ часов (11 наборов данных с 100-200 строк каждая)

Заранее спасибо!

+0

Почему в вашем результате (строка 3) есть 'NA'? – jlhoward

+0

DF1 ["3", "v6"] должно быть 400? – Emer

+0

Кроме того, строка 4 не соответствует вашим правилам. – jlhoward

ответ

2

В одну сторону, используя na.locf(...) в пакете zoo.

# replace -1,1,3 with NA 
DF1 <- as.data.frame(sapply(DF1,function(x){x[x %in% c(-1,1,3)]<-NA;x})) 
library(zoo) 
# carry last obs forward into NAs, retaining NA at the beginnig of each row 
result <- apply(DF1,1,na.locf,na.rm=FALSE) 
result <- as.data.frame(t(apply(DF1,1,na.locf,fromLast=TRUE))) 
result 
# v1 v2 v3 v4 v5 v6 v7 
# 1 350 350 350 350 350 350 7 
# 2 460 460 460 400 400 400 400 
# 3 420 420 420 420 400 200 200 
# 4 400 400 500 500 500 500 7 
# 5 400 500 500 500 500 500 500 
# 6 170 170 170 170 170 170 170 
# 7 420 420 420 420 300 300 7 
+0

Спасибо, я знал о na.locf, но не думал так далеко - для моего понимания: третий ряд заполняется из левой и четвертой справа, правильно? Насколько я понимаю, «na.locf» заменяет одно значение за раз, поэтому, если у меня есть, например, 8 отсутствующих значений, мне пришлось бы выполнять 3-ю и 4-ю строки вашего кода четыре раза? –

+0

№ Код работает как есть. 'na.locf (...)' по умолчанию заменяет все 'NA' последним значением не-NA. Поэтому 'c (400, NA, NA, NA)' становится 'c (400,400,400,400)'. Предлагаю вам ознакомиться с документацией и изучить промежуточные результаты. – jlhoward