2017-07-27 25 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