2017-10-14 50 views
0

我有endsidstarts,數據表進行計算無環路,same_person在數據表中,比較行和R中

same_person用於檢查該行是否具有相同的ID之前的一個。

library(data.table) 
id = c(1,1,2,2) 
starts = c(0,5,0,9) 
ends = c(5,10,9,20) 
same_person = c(0,0,0,0) 
df <- data.table(id, starts, ends, same_person) 

df 
     id starts ends same_person 
# 1: 1  0 5   0 
# 2: 1  5 10   0 
# 3: 2  0 9   0 
# 4: 2  9 20   0 

預期輸出有:

1.Compare兩個id的連續行,並且如果它們是相同的,替換same_person爲1
2.對於同一個人,使starts等於到第一行。

我用了2個循環來實現它們。

首先,我檢查一排id與行之前,如果相同,更換same_person爲1

for (i in 2:nrow(df)){ 
    if(df$id[i] == df$id[i-1]){ 
     df$same_person[i] <- 1 
    } 
    } 

df 
     id starts ends same_person 
# 1: 1  0 5   0 
# 2: 1  5 10   1 
# 3: 2  0 9   0 
# 4: 2  9 20   1 

基於之前的結果,我改變starts如果他們是同一個人。

for (i in 1:nrow(df)){ 
    if(df$same_person[i] == 1){ 
    df$starts[i] <- df$starts[i-1]  
    } 
} 


df 
     id starts ends same_person 
# 1: 1  0 5   0 
# 2: 1  0 10   1 
# 3: 2  0 9   0 
# 4: 2  0 20   1 

由於該數據表是一個簡化版本,所以不需要很長時間。但在我的實際工作中,這需要很多。

我在想,如果不使用循環,我可以實現這兩個步驟。

+0

什麼是預期的輸出 – akrun

+0

預期成果是:1。比較連續兩行的'id',如果他們是一樣的,更換'same_person'爲1。2,對於同一個人,使開始時間等於第一行。 – Harold

回答

0

第一行找到重複項,然後下一行用data.frame中出現的第一個值替換starts的重複項。在您的意見

df$same_person <- 1 * duplicated(df$id) 
    df$starts[which(df$same_person == 1)] <- 
     df$starts[which(df$same_person == 1) - 1] 
+0

謝謝。如果相同'id'出現兩次以上,我只需要每個id的最後一行中的'same_person'變爲1. – Harold

+0

如果我想比較兩列,該怎麼辦?例如,沒有'id'列,並且如果第二行的'starts'等於第一行的'ends'時間。他們是'same_person'。 – Harold

+0

如果你有'id's排序,那麼你會在每個副本中得到'1'。 – Suren

0

來看,似乎你想要做很多事情。在這種情況下,編寫一個循環可能會更好。

首先找到什麼是唯一的ID,然後處理它們。以下是1只是最後一行same_personid相同。

unique_ids <- unique(df$id) 
for (uid in unique_ids) { 
    n_rows <- which(df$id == uid) 
    if (length(n_rows) > 2) 
    df$same_person[max(n_rows)] <- 1 
}