2017-07-04 80 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