2017-07-27 26 views
2

以下是檢查特定條件(如果連續兩行具有相同值)後在數據框中插入新列的簡單循環。 代碼工作得很好,但我想提高我的編碼技能,所以我要求其他解決方案(更快,更優雅)。 我檢查了以前的話題,並瞭解了很多,但我對我的具體案例很好奇。 感謝您的任何輸入。改進我的編碼「for循環」

vector<-1 
vector_tot<-NULL 

    for(i in 1:length(dat$Label1)) 
    { 
    vector_tot<-c(vector_tot,vector) 
    if(dat$Label1[i]==dat$Label1[i+1]){ 
    vector<-0 
    } 
    else { 
     vector<-1 
     } 
     } 


dat$vector<- vector_tot 

回答

3

對於R中的很多事情,因爲函數是向量化的,所以不需要for循環。因此,我們可以達到你想要什麼有:

# sample data 
dat <- data.frame(Label1=c("A","B","B","C","C","C","D"),stringsAsFactors = F) 

# first create a vector that contains the previous value 
dat$next_element <- c(dat$Label1[2:nrow(dat)],"") 

# then check if they match 
dat$vector <- as.numeric(dat$Label1==dat$next_element) 

輸出:

Label1 next_element vector 
1  A   B  0 
2  B   B  1 
3  B   C  0 
4  C   C  1 
5  C   C  1 
6  C   D  0 
7  D     0 

它也可以在一行中完成,但我認爲以上說明了更好的工作原理是:

dat$vector <- dat$Label1==c(dat$Label1[2:nrow(dat)],"") 

或與之前的元素比較:

dat$vector <- dat$Label1==c("",dat$Label1[1:nrow(dat)-1]) 
+2

猜測'NA'應該在底部而非頂部(循環開始於1,它的下一個元素搜索,而不是以前的)。 – nicola

+0

'dat $ Label1 == c(tail(dat $ Label1,-1),NA)'作爲同一方法的不同概念 – thelatemail

+0

謝謝尼科拉,調整了答案。 – Florian

2

您可以在同一行做到這一點...

library(dplyr) #for the 'lead' function 
dat = data.frame(Label1=c("A","B","B","C","C","C","D"),stringsAsFactors = F) 

dat$vector <- as.numeric(dat$Label1!=lead(dat$Label1,default = "")) 

dat 
    Label1 vector 
1  A  1 
2  B  0 
3  B  1 
4  C  0 
5  C  0 
6  C  1 
7  D  1