Замените строки на 0s в фрейме данных с предыдущими значениями строк, отличными от 0
Вот пример моего фрейма данных:
df = read.table(text = 'a b
120 5
120 5
120 5
119 0
118 0
88 3
88 3
87 0
10 3
10 3
10 3
7 4
6 0
5 0
4 0', header = TRUE)
Мне нужно заменить 0 в col b
на каждое предыдущее число, отличное от 0.
Вот мой желаемый результат:
a b
120 5
120 5
120 5
119 5
118 5
88 3
88 3
87 3
10 3
10 3
10 3
7 4
6 4
5 4
4 4
До сих пор я пытался:
df$b[df$b == 0] = (df$b == 0) - 1
Но это не работает. СПАСИБО
3 ответа:
na.locf
отzoo
может помочь в этом:library(zoo) #converting zeros to NA so that na.locf can get them df$b[df$b == 0] <- NA #using na.locf to replace NA with previous value df$b <- na.locf(df$b)
Выход:
> df a b 1 120 5 2 120 5 3 120 5 4 119 5 5 118 5 6 88 3 7 88 3 8 87 3 9 10 3 10 10 3 11 10 3 12 7 4 13 6 4 14 5 4 15 4 4
Выполнение этой задачи в простом состоянии кажется довольно сложным, но вы также можете использовать небольшой цикл for вместо загрузки пакета.
for (i in which(df$b==0)) { df$b[i] = df$b[i-1] }
Вывод:
Я предполагаю, что это может быть медленным для больших данных.кадры> df a b 1 120 5 2 120 5 3 120 5 4 119 5 5 118 5 6 88 3 7 88 3 8 87 3 9 10 3 10 10 3 11 10 3 12 7 4 13 6 4 14 5 4 15 4 4
Вот базовый метод R, использующий
rle
.# get the run length encoding of variable temp <- rle(df$b) # fill in 0s with previous value temp$values[temp$values == 0] <- temp$values[which(temp$values == 0) -1] # replace variable df$b <- inverse.rle(temp)
Это возвращает
Обратите внимание, что строка замены выдаст ошибку, если первый элемент вектора равен 0. Вы можете исправить это, создав вектор, который исключает его.df a b 1 120 5 2 120 5 3 120 5 4 119 5 5 118 5 6 88 3 7 88 3 8 87 3 9 10 3 10 10 3 11 10 3 12 7 4 13 6 4 14 5 4 15 4 4
Например
replacers <- which(temp$values == 0) replacers <- replacers[replacers > 1]