Как удалить строку из объекта zoo/xts по временной метке

Я с удовольствием работал с этим кодом:

z=lapply(filename_list, function(fname){
    read.zoo(file=fname,header=TRUE,sep = ",",tz = "")
    })
xts( do.call(rbind,z) )

пока не появились Dirty Data в конце одного файла:

                        Open     High      Low    Close Volume
2011-09-20 21:00:00 1.370105 1.370105 1.370105 1.370105      1

и это в начале следующего файла:

                        Open     High      Low  Close Volume
2011-09-20 21:00:00 1.370105 1.371045 1.369685 1.3702   2230

Итак, rbind.zooжалуется на дубликат.

Я не могу использовать что-то вроде:

 y <- x[ ! duplicated( index(x) ),  ]

так как они находятся в разных объектах зоопарка, внутри списка. И я не могу использовать aggregate, как предложено здесь , потому что это список объектов зоопарка, а не один большой объект зоопарка. И я не могу получить один большой объект из-за дубликатов. Поймать -22.

Итак, когда дела идут плохо, крутой хак объединяет несколько циклов for (извинения за отпечатки и остановку, так как это еще не рабочий код):

indexes <- do.call("c", unname(lapply(z, index)))
dups=duplicated(indexes)
if(any(dups)){
    duplicate_timestamps=indexes[dups]
    for(tix in 1:length(duplicate_timestamps)){
        t=duplicate_timestamps[tix]
        print("We have a duplicate:");print(t)
        for(zix in 1:length(z)){
            if(t %in% index(z[[zix]])){
                print(z[[zix]][t])
                if(z[[zix]][t]$Volume==1){
                    print("-->Deleting this one");
                    z[[zix]][t]=NULL    #<-- PROBLEM
                    }
                }
            }
        }
    stop("There are duplicate bars!!")
    }

Бит, на котором я застрял, заключается в том, что присвоение NULL строке зоопарка не удаляет ее(Ошибка в NextMethod ("[). Итак, я делаю копию с фильтром -, без оскорбительного элемента... но я спотыкаюсь на этих:

> z[[zix]][!t,]
Error in Ops.POSIXt(t) : unary '!' not defined for "POSIXt" objects

> z[[zix]][-t,]
Error in `-.POSIXt`(t) : unary '-' is not defined for "POSIXt" objects

P.S. Хотя решения моей реальной проблемы «дублирования строк в списке объектов зоопарка» на высоком уровне -очень приветствуются, здесь вопрос конкретно о том, как удалить строку из объекта зоопарка с учетом объекта индекса POSIXt.


Небольшой бит тестовых данных:

list(structure(c(1.36864, 1.367045, 1.370105, 1.36928, 1.37039, 
1.370105, 1.36604, 1.36676, 1.370105, 1.367065, 1.37009, 1.370105, 
5498, 3244, 1),.Dim = c(3L, 5L),.Dimnames = list(NULL, c("Open", 
"High", "Low", "Close", "Volume")), index = structure(c(1316512800, 
1316516400, 1316520000), class = c("POSIXct", "POSIXt"), tzone = ""), class = "zoo"), 
    structure(c(1.370105, 1.370115, 1.36913, 1.371045, 1.37023, 
    1.37075, 1.369685, 1.36847, 1.367885, 1.3702, 1.36917, 1.37061, 
    2230, 2909, 2782),.Dim = c(3L, 5L),.Dimnames = list(NULL, 
        c("Open", "High", "Low", "Close", "Volume")), index = structure(c(1316520000, 
    1316523600, 1316527200), class = c("POSIXct", "POSIXt"), tzone = ""), class = "zoo"))

ОБНОВЛЕНИЕ:Спасибо Г. Гротендику за решение по удалению строки -. В реальном коде я последовал совету Джошуа и GSee , чтобы получить список объектов xts вместо списка объектов зоопарка. Так что мой код стал:

z=lapply(filename_list, function(fname){
    xts(read.zoo(file=fname,header=TRUE,sep = ",",tz = ""))
    })
x=do.call.rbind(z)

(Кстати, обратите внимание на вызов do.call.rbind. Это связано с тем, что rbind.xtsимеет серьезные проблемы с памятью.См.https://stackoverflow.com/a/12029366/841830)

Затем я удаляю дубликаты как пост -шаг процесса:

dups=duplicated(index(x))
if(any(dups)){
    duplicate_timestamps=index(x)[dups]
    to_delete=x[ (index(x) %in% duplicate_timestamps) & x$Volume<=1]
    if(nrow(to_delete)>0){
        #Next line says all lines that are not in the duplicate_timestamp group
        #     OR are in the duplicate timestamps, but have a volume greater than 1.
        print("Will delete the volume=1 entry")
        x=x[ !(index(x) %in% duplicate_timestamps) | x$Volume>1]
        }else{
        stop("Duplicate timestamps, and we cannot easily remove them just based on low volume.")
        }
    }

6
задан Community 23 May 2017 в 11:51
поделиться