为每个二进制部分创建唯一的 id
Create unique id for each binary section
我创建了一个二进制列 "y/n",分别用 1 和 0(是和否)表示。我现在想根据文件名和列中的位置为每个标记为 1 的部分提供一个唯一的 ID。
下面是我希望它看起来像的示例。我对 0 应该是什么没有偏好,只要标记为 1 的部分具有唯一 ID。
> 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,这只给了一个..有没有人有任何想法?
谢谢!
恩典
我们可以使用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")
另一个想法(使用@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"
我创建了一个二进制列 "y/n",分别用 1 和 0(是和否)表示。我现在想根据文件名和列中的位置为每个标记为 1 的部分提供一个唯一的 ID。 下面是我希望它看起来像的示例。我对 0 应该是什么没有偏好,只要标记为 1 的部分具有唯一 ID。
> 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,这只给了一个..有没有人有任何想法?
谢谢! 恩典
我们可以使用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")
另一个想法(使用@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"