У меня есть data.frame
, например:
set.seed(1)
df <- data.frame(id = c("A","B;C","D","E","F;G;H","I"), val1 = rnorm(6), val2 = letters[1:6], stringsAsFactors=F)
Существует столбец id
, некоторые из его значений имеют точку с запятой, указывающую, что он объединяет несколько id
с, а их значения востальные столбцы являются общими.
Для каждой строки с идентификатором с точкой с запятой:
- Я хотел бы разделить
id
разделителем точек с запятой - реплицирует эту
data.frame
строку на количество id
s, которые были разбиты - случайным образом
shuffle
порядок реплицированных data.frame
- заменяет исходную строку в
df
с той, которую я создал в 3, так что порядок всех других строк в df
не изменился.
Вот моя громоздкая попытка:
idx <- which(grepl(";",df$id))
l <- lapply(idx, function(i){
ids <- strsplit(df$id[i], split = ";")[[1]]
df.i <- do.call("rbind", replicate(length(ids), df[i,,drop=F], simplify = FALSE))
df.i$id <- ids[permute::shuffle(ids)]
return(df.i)
})
idx.names <- df$id[idx]
for(i in 1:length(idx.names)){
df <- rbind(df[1:(which(df$id == idx.names[i])-1),,drop=F],
l[[i]],
df[(which(df$id == idx.names[i])+1):nrow(df),,drop=F])
}
Итак, я 'ищу что-то более элегантное (возможно, используя tidyverse
или data.table
) и быстрее.