搜索R

时间:2017-07-04 04:29:10

标签: r search dataframe data.table

我有一个关于在R中搜索值的问题,它实际上有点类似于昨天发布的问题(在这里给出:Searching a vector/data table backwards in R)除了我认为我的问题有点复杂(而且与我想做的事情相反),因为我对R很新,所以我不太清楚如何解决这个问题。

我有一个类似于下面给出的数据框,我希望找到我当前的索引值,其中Times列与我当前时间不同而Midquote列确实如此没有NA值。

Index               Times    |    Midquote
                -----------------------------
   1            10:30:45.58  |    5.319
   2            10:30:45.93  |    5.323
   3            10:30:45.104 |    5.325
   4            10:30:45.127 |    5.322
   5            10:30:45.188 |    5.325
   6            10:30:45.188 |    NA
   7            10:30:45.212 |    NA
   8            10:30:45.231 |    5.321
   9            10:30:45.231 |    5.321

如果我们从数据框的底部开始,并将其作为当前的'时间,这被发现是在索引9,Times10:30:45.231Midquote5.321,然后如果我想找到第一个索引时间与我当前的时间不同,我们发现这被发现是索引7,其时间为10:30:45.212(因为索引8具有相同的时间)。但我们也看到在索引7处Midquote值为NA,因此我现在必须再次检查数据框。索引6再次具有不同的时间(即10:30:45.188),但它在NA列中再次具有Midquote值,因此再次向上移动到索引5,我们看到{{1 }}列与当前时间的时间不同(即Times再次),10:30:45.188值为Midquotes

因此,因为在索引5处的时间是5.325(这与我当前时间10:30:45.188不同)并且因为索引5处的10:30:45.231值不是{{1我想获得输出' 5'因为它是满足两个标准的指数值。

我的问题是,有这样做的好方法吗?我很抱歉,如果这是一个简单的问题,我对R来说很新,我对使用数据框不太了解......

编辑:我还想最好不要在数据框中添加另一列(如上面提到的链接的最佳答案中所示),如果可能的话

3 个答案:

答案 0 :(得分:2)

使用日期很难,尤其是小数秒。 如果你可以把时间转换成双打,那么就更容易使用了。 假设你的'时代''你可以使用这个

library(magrittr)
which(df$Times < df[9,1] & !is.na(df$Midquote)) %>% max()

which给出了&#39;索引&#39;的向量。在哪里&#39;时代&#39;比9中的少得多,而且中等命中率为&#39;不是NA。 %>%将向量发送到max(),它给出了最高值。这是非常不优雅的,但将完成工作。

答案 1 :(得分:1)

如果我理解正确,请检查这是否是您期望的输出。

ind<-function(t,df){
    ind<-t
    while(t>1){
       t=t-1
        if((df$Times[t]!=df$Times[ind]) && (!is.na(df$Midquote[t]))){
            return(t)
        }
    }
}
sapply((nrow(data):1),FUN = ind,data)

#[[1]]
#[1] 5

#[[2]]
#[1] 5

#[[3]]
#[1] 5

#[[4]]
#[1] 4

#[[5]]
#[1] 4

#[[6]]
#[1] 3

#[[7]]
#[1] 2

#[[8]]
#[1] 1

#[[9]]
#NULL

输出系列对应于从最后一行开始的data.frame的关联索引。

说明:ind将行号的值作为当前行,而tind-1开始取值为dfwhile将整个data.frame作为输入,然后df$Times[t]循环用于检查df$Midquote[t]sapply的时间和中间值是否满足所需条件。如果是,则返回索引,否则循环继续,直到到达第一行。

不使用 ind(9,df) [1] 5 表示特定的当前行:

class IService {
    virtual void DoWork() = 0;
    virtual bool IsRunning() = 0;
};

class ClientA : IService {
    void DoWork() {
        std::cout << "Work in progress inside A";
    }
    bool IsRunning() { 
        return true; 
    }
};

class ClientB : IService {
    void DoWork() {
        std::cout << "Work in progress inside B";
    }
    bool IsRunning() {
        return true;
    }
};

class Server {
    IService* _service;
    Server(IService* service) : _service(service)
    { }

    // Error: this declaration has no storage class or type specifier
    // Compiler: MSVC 2017
    _service->DoWork();
};

答案 2 :(得分:1)

zip.AddFile()解决方案,1行。

Data.table

修改

要删除索引列,您(至少)有两个选项

library(data.table)

dt <- data.table(Index = 1:9,
                 Times = c( '10:30:45.58', '10:30:45.93','10:30:45.104','10:30:45.127','10:30:45.188','10:30:45.188','10:30:45.212','10:30:45.231','10:30:45.231' ),
                 Midquote = c('5.319','5.323','5.325','5.322','5.325',NA,NA,'5.321','5.321')
                )

> dt[ Times != Times[.N] & !is.na(Midquote), max(Index) ]
[1] 5

NB 您无法dt2 <- data.table(Times = c( '10:30:45.58', '10:30:45.93','10:30:45.104','10:30:45.127','10:30:45.188','10:30:45.188','10:30:45.212','10:30:45.231','10:30:45.231' ), Midquote = c('5.319','5.323','5.325','5.322','5.325',NA,NA,'5.321','5.321')) # Option 1 - create an id column on the fly (unfortunately data.table recalculate .I after evaluating the "where" clause... so you need to save it) dt2[, cbind(.SD, id=.I)][ Times != Times[.N] & !is.na(Midquote), max(id) ] # Option 2 - simply check the last position of where your condition is met dt2[, max(which(Times != Times[.N] & !is.na(Midquote))) ] ,因为您可以拥有符合条件的第1,第2和第4条记录,nrow会给出你3,这是错误的,因为第3行不匹配。

编辑2 (选项3不是正确

nrow