R重复并增加数据框列的数量,基于不同列中的文本

时间:2014-02-19 10:29:32

标签: r text increment repeat

我有一个由以下内容组成的数据框:

df[1] <- c(red, white, blue, Flag, red, yellow, black, Flag, Flag, white, red, Flag)

我希望旁边有一个列表,其中包含不列出双打的标志数字,除非它们之间报告颜色。 所以它应该是:

df[2] <- c(1,1,1,1,2,2,2,2,2,3,3,3) 

我有一个代码在for循环中执行此操作:

#list of unique Flags
numrows<-nrow(df[1])
df[2]<-rep(1,numrows)

counter<-1
for (i in 1:12){
  if (df[i,1]=="Flag" & df[i+1,1]!="Flag"){
    df[i,2]<-counter

    counter<-counter+1
  }else{
    df[i,2]<-counter
  }
}
df[numrows,2]<-counter

问题是我的完整数据集有650.000行,需要8个多小时。有没有办法在R中没有for循环的情况下得到这个特定的结果?

1 个答案:

答案 0 :(得分:1)

以下是使用cumsum()data.table()的稍微复杂的解决方案 - 利用.SD对象仅标记具有颜色跟随的“标志”。我确信通过一些思考可以使它更加简洁。

650k行的6.24秒

require(data.table)
# function to return leading 1 and trailing 0s for each instance of flag
# no 1 returned for single instance (duplicate)
get_s<-function(x){
  ifelse(x==1,
         y<-c(0),
         y<-c(1,rep(0,x-1))
  )
  return(y)
}

system.time({
  df<-data.frame(V1=sample(c("red", "white", "blue", "Flag", "yellow", "black"),650000,T)) #650k rows
  df$V2<-cumsum(ifelse(df$V1=="Flag",1,0))                                                 #index each "Flag"
  df$V2<-cumsum(data.table(df,key="V2")[,list(get_s(nrow(.SD))),by="V2"][,V1])             #return 1 for Flags with following color
})

#user  system elapsed 
#6.16    0.06    6.24