Оригинал Ответ: Смотрите ниже обновления.
Во-первых, я сделал ваши данные примера более сложными, добавив первую строку в нижнюю.
dff <- structure(list(code = c("61000-61003", "0169T-0169T", "61000-61003"
), label = c("excision of CNS", "ventricular shunt", "excision of CNS"
)), .Names = c("code", "label"), row.names = c(NA, 3L), class = "data.frame")
dff
# code label
# 1 61000-61003 excision of CNS
# 2 0169T-0169T ventricular shunt
# 3 61000-61003 excision of CNS
Мы можем использовать оператор последовательности :
, чтобы получить последовательности для code
колонны, обертывание tryCatch()
таким образом мы можем избежать ошибки на, и сохранить значения, которые не могут быть виртуализированных. Сначала разделим значения на метку -
, затем запустите ее через lapply()
.
xx <- lapply(
strsplit(dff$code, "-", fixed = TRUE),
function(x) tryCatch(x[1]:x[2], warning = function(w) x)
)
data.frame(code = unlist(xx), label = rep(dff$label, lengths(xx)))
# code label
# 1 61000 excision of CNS
# 2 61001 excision of CNS
# 3 61002 excision of CNS
# 4 61003 excision of CNS
# 5 0169T ventricular shunt
# 6 0169T ventricular shunt
# 7 61000 excision of CNS
# 8 61001 excision of CNS
# 9 61002 excision of CNS
# 10 61003 excision of CNS
Мы пытаемся применить оператор последовательности :
к каждому элементу из strsplit()
, и если принимать x[1]:x[2]
не представляется возможным, то это возвращает только значения для этих элементов и протекает с последовательностью x[1]:x[2]
иначе. Затем мы просто повторяем значения столбца label
на основе результирующих длин в xx
, чтобы получить новый столбец label
.
Update: Вот что я придумал в ответ на ваши изменения. Заменить xx
выше
xx <- lapply(strsplit(dff$code, "-", TRUE), function(x) {
s <- stringi::stri_locate_first_regex(x, "[A-Z]")
nc <- nchar(x)[1L]
fmt <- function(n) paste0("%0", n, "d")
if(!all(is.na(s))) {
ss <- s[1,1]
fmt <- fmt(nc-1)
if(ss == 1L) {
xx <- substr(x, 2, nc)
paste0(substr(x, 1, 1), sprintf(fmt, xx[1]:xx[2]))
} else {
xx <- substr(x, 1, ss-1)
paste0(sprintf(fmt, xx[1]:xx[2]), substr(x, nc, nc))
}
} else {
sprintf(fmt(nc), x[1]:x[2])
}
})
Да, это сложно. Теперь, если мы возьмем следующий кадр df2
данных в качестве тестового примера
df2 <- structure(list(code = c("61000-61003", "0169T-0174T", "61000-61003",
"T0169-T0174"), label = c("excision of CNS", "ventricular shunt",
"excision of CNS", "ventricular shunt")), .Names = c("code",
"label"), row.names = c(NA, 4L), class = "data.frame")
и запустить xx
код сверху на него, мы можем получить следующий результат.
data.frame(code = unlist(xx), label = rep(df2$label, lengths(xx)))
# code label
# 1 61000 excision of CNS
# 2 61001 excision of CNS
# 3 61002 excision of CNS
# 4 61003 excision of CNS
# 5 0169T ventricular shunt
# 6 0170T ventricular shunt
# 7 0171T ventricular shunt
# 8 0172T ventricular shunt
# 9 0173T ventricular shunt
# 10 0174T ventricular shunt
# 11 61000 excision of CNS
# 12 61001 excision of CNS
# 13 61002 excision of CNS
# 14 61003 excision of CNS
# 15 T0169 ventricular shunt
# 16 T0170 ventricular shunt
# 17 T0171 ventricular shunt
# 18 T0172 ventricular shunt
# 19 T0173 ventricular shunt
# 20 T0174 ventricular shunt
Хммм Я не очень разбираюсь в data.table, но я не вижу, как ваш экзамен может работать - 'Code_1' (не должно быть' code_1'?), А 'code_2' должен быть числовым, если вы хотите построить последовательность, например 'hcup <- read.table (header = T, strAsAsFactors = F, text =" метка кода \ n61000-61003 excision_of_CNS \ n0169T-0169T ventricular_shunt "); cSplit (hcup, "code", "-") [, list (Code = seq (as.integer (gsub ("\\ D", "", code_1)), as.integer (gsub ("\\ D" , "", code_2)))), by = label] '. – lukeA
Спасибо. Я принял изменения. Я не особо отношусь к «splitstackshape» как таковой. Есть ли возможность написать функцию, которая может справиться с этой проблемой? – x1carbon
Это может быть полезно из документации 'splitstackshape': если вы знаете, что все значения в столбце будут иметь одинаковое количество значений для каждой строки после разделения, вместо этого вы должны использовать функцию' cSplit_f', которая использует 'fread' вместо 'strsplit' и, как правило, быстрее. –