Вы были близки, просто добавьте 1:x
последовательности (обозначенные #
) вместо отдельных значений.
data.dt$new <- NA
data.dt$rest <- NA
for (i in 2:nrow(data.dt)) {
if(data.dt$priority[i] <= data.dt$priority[i-1]) {
data.dt$new[[i]] <- data.dt$category[i]
data.dt$rest[[i]] <- toString(data.dt$category[1:(i-1)]) #
}
else{
data.dt$new[[i]] <- data.dt$category[i-1]
data.dt$rest[[i]] <- toString(data.dt$category[1:i]) #
}
}
# priority category new rest
# 1: 3 a <NA> <NA>
# 2: 2 b b a
# 3: 1 c c a, b
# 4: 4 d c a, b, c, d
# 5: 5 e d a, b, c, d, e
# 6: 6 f e a, b, c, d, e, f
# 7: 7 g f a, b, c, d, e, f, g
В качестве альтернативы вы можете сделать это без цикла for
, используя diff
. (Вам не нужно заранее создавать NA
с.)
data.dt$new <-
with(data.dt, ifelse(c(NA, diff(priority)) < 0, category, c(NA, category)))
Объяснение: diff
вычисляет разницу для каждого значения из его предыдущего значения; мы применяем ifelse
(который векторизован if
и else
) при условии, если diff
равно < 0
.
sl <- c(NA, Map(function(x) toString(data.dt$category[seq(x)]), seq(nrow(data.dt))))
data.dt$rest <- ifelse(c(NA, diff(data.dt$priority)) < 0, sl, sl[-1])
data.dt
# priority category new rest
# 1: 3 a <NA> NA
# 2: 2 b b a
# 3: 1 c c a, b
# 4: 4 d c a, b, c, d
# 5: 5 e d a, b, c, d, e
# 6: 6 f e a, b, c, d, e, f
# 7: 7 g f a, b, c, d, e, f, g
Обновление
Чтобы избавиться от значений в столбце rest
, появляющемся в столбце new
, вы можете опустить match
es с помощью этого кода:
sc <- Map(function(x) c(data.dt$category[seq(x)]), seq(nrow(data.dt)))
data.dt$rest <- unlist(c(NA, Map(function(x, y)
toString(x[is.na(match(x, y))]), sc, data.dt$new)[-1]))
Объяснение: Для столбца rest
мы хотим seq
uences sc
с длиной фактической строки, которую мы достигаем с Map
. Поскольку мы не хотим, чтобы эти значения уже появлялись в столбце new
, мы match
sc
с data.dt$new
перед применением toString
. unlist
дает нам вектор, потому что нам не нужен столбец списка классов.
Просмотр ?Map
показывает, что он последовательно применяет FUN
ction к следующим двум объектам в том же порядке : Map(FUN, x, y)
. Результаты собраны в список. Для четвертых элементов, которые выглядят так:
# Map(FUN, x, y)
(x <- sc[[4]])
# [1] "a" "b" "c" "d"
(y <- data.dt$new[[4]])
# [1] "c"
toString(x[is.na(match(x, y))]) # FUN
# [1] "a, b, d"
Результат
data.dt
# priority category new rest
# 1 3 a <NA> <NA>
# 2 2 b b a
# 3 1 c c a, b
# 4 4 d c a, b, d
# 5 5 e d a, b, c, e
# 6 6 f e a, b, c, d, f
# 7 7 g f a, b, c, d, e, g
Данные
data.dt <- structure(list(priority = c(3, 2, 1, 4, 5, 6, 7), category = c("a",
"b", "c", "d", "e", "f", "g")), row.names = c(NA, -7L), class = c("data.table",
"data.frame"))