为每个二进制部分创建唯一ID

时间:2017-04-20 06:11:02

标签: r unique

我制作了一个二进制列" y / n"由1和0表示(是和否,分别)。我现在想根据文件名和列中的位置给每个标记为1的部分一个唯一的id。 下面是我希望它的样子。只要标记为1的部分具有唯一ID,我就不会优先选择0。

> y/n         id                       
> 1                    catid_a                 
> 1                    catid_a                                      
> 1                    catid_a                 
> 0                    no_id                                     
> 1                    catid_b                                     
> 1                    catid_b                 
> 0                    no_id 

通常命名我使用的id data$id <- as.factor(substr(basename(files[i]),1,13)) 但是在这种情况下它不起作用,因为我想在列中有多个id,这只是给出一个......有没有人有任何想法?

谢谢! 恩典

2 个答案:

答案 0 :(得分:1)

我们可以使用rle

df1$id <-inverse.rle(within.list(rle(df1$`y/n`), {val1 <- values
               val1[values!=0] <- paste0("catid_", letters[seq_along(values[values!=0])])
              val1[values==0] <- "no_id"
                values <- val1}))
df1$id
#[1] "catid_a" "catid_a" "catid_a" "no_id"   "catid_b" "catid_b" "no_id"  

或其他选项rleid来自data.table

library(data.table)
setDT(df1)[, grp := rleid(`y/n`)][`y/n`==0,  id := 'no_id' ,grp
      ][is.na(id), id := paste0("catid_", letters[.GRP]), grp][, grp := NULL][]
#   y/n      id
#1:   1 catid_a
#2:   1 catid_a
#3:   1 catid_a
#4:   0   no_id
#5:   1 catid_b
#6:   1 catid_b
#7:   0   no_id

数据

df1 <- structure(list(`y/n` = c(1, 1, 1, 0, 1, 1, 0)), .Names = "y/n", row.names = c(NA, 
 -7L), class = "data.frame")

答案 1 :(得分:1)

另一个想法(使用@ akrun的数据集),

y <- replace(paste0('catid_', cumsum(c(1, diff(df1$`y/n`) != 0))), df1$`y/n` == 0, 'no_id')

y
#[1] "catid_1" "catid_1" "catid_1" "no_id"   "catid_3" "catid_3" "no_id"

要使值成为连续值,我们需要添加几行并包含一个包

yy <- as.numeric(gsub('\\D+', '', y[grepl('[0-9]+', y)]))
y[grepl('[0-9]+', y)] <- stringi::stri_replace_all_regex(y[grepl('[0-9]+', y)], '[0-9]+', 
                                                                 cumsum(c(1, diff(yy)!=0)))

y
#[1] "catid_1" "catid_1" "catid_1" "no_id"   "catid_2" "catid_2" "no_id"