我发现这是使用factor 并仔细设置levels 的完美案例。我将在这里使用data.table 来表达这个想法。确保您的 value 列是 character(不是绝对要求)。
-
第 1 步:只需使用 unique 行,即可将您的 data.frame 转换为 data.table。
require(data.table)
dt <- as.data.table(unique(df))
setkey(dt, "depth") # just to be sure before factoring "value"
-
第 2 步:将 value 转换为 factor 并强制转换为 numeric。确保自己设置关卡(这很重要)。
dt[, id := as.numeric(factor(value, levels = unique(value)))]
-
第 3 步:将键列设置为 depth 以进行子集化,只需选择最后一个值
setkey(dt, "depth", "id")
dt.out <- dt[J(unique(depth)), mult="last"][, value := NULL]
# depth id
# 1: 1 2
# 2: 2 2
# 3: 3 3
-
第 4 步:由于深度增加的行中的所有值都应至少具有上一行的值,因此您应该使用cummax 来获得最终输出。
dt.out[, id := cummax(id)]
编辑:以上代码仅用于说明目的。实际上,您根本不需要第三列。这就是我编写最终代码的方式。
require(data.table)
dt <- as.data.table(unique(df))
setkey(dt, "depth")
dt[, value := as.numeric(factor(value, levels = unique(value)))]
setkey(dt, "depth", "value")
dt.out <- dt[J(unique(depth)), mult="last"]
dt.out[, value := cummax(value)]
这是一个更棘手的例子和代码的输出:
df <- structure(list(depth = c(1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 6),
value = structure(c(1L, 2L, 3L, 4L, 1L, 3L, 4L, 5L, 6L, 1L, 1L),
.Label = c("a", "b", "c", "d", "f", "g"), class = "factor")),
.Names = c("depth", "value"), row.names = c(NA, -11L),
class = "data.frame")
# depth value
# 1: 1 2
# 2: 2 4
# 3: 3 4
# 4: 4 5
# 5: 5 6
# 6: 6 6