2016-01-06 1 views
0

Я пытаюсь удалить строки, в которых объем равен 0, а также строки непосредственно под этими строками. Итак, для df ниже я хотел бы удалить третий и четвертый строки.Как вы используете 'lead' для удаления строки после спецификатора?

head(data1) 
      open high low close volume adj. 
2013-12-23 6.32 6.36 6.21 6.22 329400 6.22 
2013-12-24 6.27 6.36 6.22 6.30 126500 6.30 
2013-12-25 6.30 6.30 6.30 6.30  0 6.30 
2013-12-26 6.30 6.36 6.23 6.23 126600 6.23 
2013-12-27 6.26 6.28 6.20 6.24 54000 6.24 
2013-12-30 6.24 6.50 6.24 6.44 61000 6.44 

У меня есть решение, которое работает, но постыдно долго и неаккуратно:

if.zero.or.not <- as.data.frame(data1$volume == 0) 
combinded.data = bind_cols(data1, if.zero.or.not) 
colnames(combinded.data) = c('open', 'high', 'low', 'close', 'volume', 'adj.', 'ifzero') 
combinded.data.shifted = transform(combinded.data, ifzero = lag(ifzero)) 
zeros.and.trues.removed = subset(trues.removed, volume != 0, ifzero != T) 

Как я могу сделать это в одну или две линии? Спасибо за вашу помощь!

+1

Не могли бы вы просто использовать 'which'? –

+3

'idx <- который (data1 $ volume == 0); data1 [-c (idx, idx + 1L),] '(может потребоваться дополнительная помощь, если возможно, чтобы последняя строка была 0, возможно,' setdiff (c (idx, idx + 1L), nrow (data1)) ' это самый простой способ) – MichaelChirico

+0

@MichaelChirico Вы должны разместить это как ответ. –

ответ

2

Я напишу в data.table, потому что предпочитаю синтаксис; перевод на base прост.

library(xts) #Needed to get the following "xts" "zoo" object 
data1 <- structure(c(6.32, 6.27, 6.3, 6.3, 6.26, 6.24, 6.36, 6.36, 6.3, 
6.36, 6.28, 6.5, 6.21, 6.22, 6.3, 6.23, 6.2, 6.24, 6.22, 6.3, 
6.3, 6.23, 6.24, 6.44, 329400, 126500, 0, 126600, 54000, 61000, 
6.22, 6.3, 6.3, 6.23, 6.24, 6.44), .Dim = c(6L, 6L), .Dimnames = list(
    NULL, c("open", "high", "low", "close", "volume", "adj.")), index = structure(c(1387756800, 
1387843200, 1387929600, 1388016000, 1388102400, 1388361600), tzone = "UTC", tclass = "Date"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC", class = c("xts", 
"zoo")) 

library(data.table) 
#setDT fails on "xts" "zoo" object. We need as.data.table 
#setDT(data1) #convert to native 'data.table' class _by reference_ 

data1 <- as.data.table(data1) 
data1[if (!length(rows <- -c(idx <- which(volume == 0), (if (volume[.N] == 0) idx[-length(idx)] else idx) + 1L))) TRUE else rows] 

Если вы таблица достаточно большая, и есть много кластерных нулей, это должно быть более эффективным, чтобы обернуть c(...) в unique.

Если у вас есть структурные причины, чтобы знать, последняя строка не будет равна нулю, эта версия легче на глазах:

data1[if (!length(rows <- -c(idx <- which(volume == 0), idx + 1L))) TRUE else rows] 

+0

@MichaelChirico, извините, что снова вернул вас к этому! Я получаю сообщение об ошибке: «Предупреждающее сообщение: В [.data.table (data, if (! Length (rows <- -c (idx <- which (volume ==: ) Пункт 16 of i is -728, который произошел раньше. Игнорирование этого и 13 других дубликатов из 29. «Сначала я думал, что он игнорирует тот факт, что были дубликаты, но после прочтения его снова выглядит так, что это означает, что он выполняет операцию_ на дубликатах, что является проблемой ... – RyGuy

+1

@RyGuy нет, на самом деле это не так. cf. 'data.table (a = 1: 3) [- c (1,1)]'. Если вы все еще не уверены, просто обходите 'c (...)' выше с 'unique'. – MichaelChirico

0

Это может помочь. Это пример с образцами данных.

a<-c(1,0,9,7,5,0,7,0) 
b<-c(1,9,6,7,4,5,7,8) 
dc<-data.frame(a,b) 
dc_removed_zero_and_the_next_row<-dc[-c(which(dc$a==0),which(dc$a==0)+1),] 
+1

idx <- который (data1 $ volume == 0); data1 [-c (idx, idx + 1L)] (может потребоваться больше, если возможно, чтобы последняя строка была 0, возможно, setdiff (c (idx, idx + 1L), nrow (data1)) является самым простым way) - MichaelChirico 43 мин назад –

+2

обратите внимание, что это дважды вычисляет вектор индекса, что неэффективно, если 'data.frame' тривиально мало. также, как я уже упоминал, вам нужно иметь дело с пограничным случаем - это вернет ошибку, если последняя запись равна 0. – MichaelChirico