2017-07-04 29 views
4

我有一个关于在R中搜索值的问题,它实际上有点类似于昨天发布的问题(如在这里给出的:Searching a vector/data table backwards in R),除了我认为我的问题是有点复杂(也与我想做的相反),并且由于我对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和其具有10:30:45.231一个Times值和5.321Midquote值,那么如果我想找到时间与当前时间不同的第一个索引,我们发现这是索引7,它的时间为10:30:45.212(因为索引8具有相同的时间)。但是我们也看到索引7处的Midquote的值是NA,所以我现在必须再次检查数据帧。索引6又有一个不同的时间(即10:30:45.188),但它在Midquote列中又有一个NA值,因此再次向索引5移动,我们看到Times列与当前时间有不同的时间(即再次为10:30:45.188)并且Midquotes的值是5.325

因此,由于在索引5的时间10:30:45.188(这是不同的,以我的当前时间,这是10:30:45.231),并且由于在索引5的Midquote值不NA,我希望获取的输出“5”,因为它是满足两个标准的指标值。

我的问题是,有没有这样做的好方法?我很抱歉,如果这是一个简单的问题,我是非常新的R和我不知道太多有关数据帧的工作...

编辑:我也想这样做最好不添加另一列数据帧(如上面提到的链接的顶部答案中给出的),如果可能的话

+0

您可以显示预期的输出? – akrun

+0

对不起,这是什么意思?我希望能够从数据框中获得索引5,因为“时间”与我当前的时间不同(因为我从数据框的最底部开始)和“ Midquote'不是'NA' – reallybadstatdude

+0

显示你想要的数据看起来像什么,即你的问题的“答案”是什么样子的示例数据。如果你在数据中显示所有相关行的答案(不仅仅是索引9),这会有所帮助,因为这可以使确切的规则更清晰。 – Marius

回答

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取为当前行的行数的值,而t需要从ind-1起始值为1 df拍摄整个data.frame作为输入,则使用循环while检查是否时间和midlands值为df$Times[t]df$Midquote[t]满足要求的条件。如果是,他们返回索引,否则循环继续,直到到达第一行。

不使用sapply特定当前行:

ind(9,df) 
[1] 5 
+0

谢谢,这似乎是我寻找的东西:)你能解释什么需要sapply功能吗?我试着用函数输入它,但它不能正常工作,我不太熟悉它的作用 – reallybadstatdude

+1

sapply通常用于循环R中的矢量或列表而不使用for循环...因为,我认为你需要索引每个我使用sapply的行元素。 – TUSHAr

+1

@reallybadstatdude在函数中添加了解释并纠正了一个错字。希望它现在适合你。 – TUSHAr

2

使用日期是特别小数秒强硬。 如果您可以将时间转换为双倍,那么处理起来会更容易。 假设你的“纽约时报”都是为了你可以使用这个

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

which给出了“索引”,其中“纽约时报”是小于9和“Midquote”不是NA的向量。 %>%将向量发送给max(),它给出了最高值。这相当不雅,但会完成工作。

1

Data.table解决方案,1行。

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 

编辑

要删除你的索引列(至少)两个选项

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

NB你不能这样做,因为nrow你可以有,比方说,与您的条件匹配的第一,第二和第四条记录和nrow会给您3,这是错误的,因为第三行不匹配。

EDIT 2(选项3是不正确的

dt3 <- 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', NA,'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) 
dt3[, cbind(.SD, id=.I)][ Times != Times[.N] & !is.na(Midquote), max(id) ] 
[1] 5 

# Option 2 - simply check the last position of where your condition is met 
dt3[, max(which(Times != Times[.N] & !is.na(Midquote))) ] 
[1] 5 

# Option 3 - good luck with this 
nrow(dt3[Times != Times[.N] & !is.na(Midquote)]) 
[1] 4 
+0

这似乎相当有效,但有没有办法做到这一点,而不创建一个新的列?此外,请纠正我,如果我错了,但从我可以告诉函数似乎向前移动通过数据表,而不是向后移动数据表。因为我需要向后移动数据表,所以这可能不合适(但当然我可能会错误地解释它) – reallybadstatdude

+0

对不起,请忽略我以前的评论,我想我明白了为什么你现在使用了max()函数。我只是想知道,这是否会替代你写的内容:nrow((df2 [Times!= Times [i]&!is.na(Midquote)]))?这样我不需要创建一个新的索引列。请注意,通过上面的Times [i]'代码中的'i',我只是指一个通用索引值(因为索引可能会改变,可能不一定是数据表的最后一个值) – reallybadstatdude

+0

@reallybadstatdude请检查我的编辑 – Michele