base
solutionind <- 2:5
path.seq <- seq_len(max(rowSums(df[ind])))
mat <- apply(df[ind] > 0, 1, \(x) names(which(x))[path.seq])
row.names(mat) <- paste0("path", path.seq)
cbind(df, t(mat))
# ID 1_0_1_0 1_0_0_0 2_0_1_0 2_0_3_0 path1 path2
# 1 1 1 0 1 0 1_0_1_0 2_0_1_0
# 2 2 0 0 1 0 2_0_1_0 <NA>
# 3 3 0 1 0 0 1_0_0_0 <NA>
Update:将第
mat
行替换如下,以处理列可以采用任何非负整数的情况.mat <- apply(df[ind], 1, \(x) rep(names(df)[ind], x)[path.seq])
tidyverse
solutionlibrary(tidyverse)
df %>%
pivot_longer(-ID) %>%
filter(value > 0) %>%
# uncount(value) %>%
mutate(path = paste0("path", row_number()), .by = ID) %>%
pivot_wider(id_cols = ID, names_from = path, values_from = name) %>%
left_join(df, ., by = "ID")
Update:在
filter()
和mutate()
之间插入uncount(value)
,以处理列可以采用任何非负整数的情况.
df %>%
mutate(
across(-ID, ~ if_else(.x > 0, cur_column(), NA)) %>%
unite("path", sep = ';', na.rm = TRUE)
) %>%
separate_wider_delim(path, delim = ';', names_sep = '', too_few = "align_start")
# # A tibble: 3 × 7
# ID `1_0_1_0` `1_0_0_0` `2_0_1_0` `2_0_3_0` path1 path2
# <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
# 1 1 1 0 1 0 1_0_1_0 2_0_1_0
# 2 2 0 0 1 0 2_0_1_0 NA
# 3 3 0 1 0 0 1_0_0_0 NA