给定时间戳,如何从 zoo/xts 对象中删除一行 [英] How to remove a row from zoo/xts object, given a timestamp

查看:32
本文介绍了给定时间戳,如何从 zoo/xts 对象中删除一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很高兴使用此代码运行:

I was happily running with this code:

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

直到脏数据出现在一个文件的末尾:

until Dirty Data came along with this at the end of one file:

                        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,因为 此处建议 因为它们是动物园对象的列表,而不是一个大型动物园对象.而且我无法得到一个大对象重复项的cos".第 22 条军规.

as they are in different zoo objects, inside a list. And I cannot use aggregate, as suggested here because they are a list of zoo objects, not one big zoo object. And I can't get one big object 'cos of the duplicates. Catch-22.

因此,当事情变得艰难时,艰难的将一些 for 循环组合在一起(请原谅打印和停止,因为这还不是工作代码):

So, when the going gets tough, the tough hack together some for loops (excuse the prints and a stop, as this isn't working code yet):

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 中的错误([<-"):替换长度为零).好的,所以我做了一个过滤复制,没有违规项目......但我被这些绊倒了:

The bit I've got stumped on is assigning NULL to a zoo row doesn't delete it (Error in NextMethod("[<-") : replacement has length zero). OK, so I do a filter-copy, without the offending item... but I'm tripping up on these:

> 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

附言虽然对我的跨动物园对象列表重复行"的实际问题的高级解决方案非常受欢迎,但这里的问题特别是关于如何从给定 POSIXt 索引对象的动物园对象中删除一行.

P.S. While high-level solutions to my real problem of "duplicates rows across a list of zoo objects" are very welcome, the question here is specifically about how to delete a row from a zoo object given a POSIXt index object.

一小部分测试数据:

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"))

<小时>

更新:感谢 G.Grothendieck 用于行删除解决方案.在实际代码中,我遵循了 JoshuaGSee 获取 xts 对象列表而不是动物园对象列表.所以我的代码变成了:


UPDATE: Thanks to G. Grothendieck for the row-deleting solution. In the actual code I followed the advice of Joshua and GSee to get a list of xts objects instead of a list of zoo objects. So my code became:

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)

(As an aside, please note the call to do.call.rbind. This is because rbind.xts has some serious memory issues. See https://stackoverflow.com/a/12029366/841830 )

然后我删除重复项作为后处理步骤:

Then I remove duplicates as a post-process step:

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.")
        }
    }

推荐答案

如果 z1z2 是你的动物园对象,那么 rbind 而删除 z2 中的任何重复项:

If z1 and z2 are your zoo objects then to rbind while removing any duplicates in z2:

rbind( z1, z2[ ! time(z2) %in% time(z1) ] )

关于在动物园对象中删除具有指定次数的点,上面已经说明了这一点,但一般来说,如果 tt 是要删除的次数向量:

Regarding deleting points in a zoo object having specified times, the above already illustrates this but in general if tt is a vector of times to delete:

z[ ! time(z) %in% tt ]

或者如果我们知道 tt 中只有一个元素,那么 z[ time(z) != tt ] .

or if we knew there were a single element in tt then z[ time(z) != tt ] .

这篇关于给定时间戳,如何从 zoo/xts 对象中删除一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆