data.table:将行方式粘贴函数应用于列

时间:2017-09-09 10:10:54

标签: r data.table

我正在寻求以下问题的帮助。 我有一个data.table,其分层标识符由五个级别组成。格式为[level_1]-[level_2]-[level_3].[level_4].[level_5](注意连字符分隔级别1,2和3与3,4和5之间的时间段)。我把它做得比我的实际数据(有6个级别)略小 - 我认为这个解决方案的工作方式是一样的。

一些玩具数据:

my_dt = setDT(data.frame("level_1" = c("H111", "H111", "H111", "H222", "H222", "H333"), "level_2" = c("a12", "a12", "b12", "c12", "c12", NA),
                   "level_3" = c("B9", "B2", "G1", NA, "F4", NA),
                   "level_4" = c("11", NA, "55", NA, "66", NA), 
                   "level_5" = c("A", NA, "B", NA, NA, NA),
                   "key_level" = c(5,3,5,2,4,1)))

例如,组合时的上述标识符应如下所示(如果它们以“关键级别”(或层次结构深度,如果您愿意)进行报告。

    full_key = c("H111-a12-B9.11.A", "H111-a12-B2", "H111-b12-G1.55.B", "H222-c12", "H222-c12-F4.66", "H333")

我想帮助编写一个具有所需层次结构深度(hlevel)的函数,并将密钥报告给该特定深度(仅当key_level为> = {{ 1}},否则返回NA)。

例如,如果我想将上面的示例报告到第3级,我希望得到以下结果:

hlevel

(如您所见,所有具有key_level< 3的行应为NA)。

我正在努力让这个工作。这是我的尝试(可能比实际阅读问题更令人困惑!)。此解决方案仅设置分隔符为“。”的键的开头,并且无法为具有to_level_3 = c("H111-a12-B9", "H111-a12-B2", "H111-b12-G1", NA, "H222-c12-F4", NA) <的行的那些行返回NA。比key_level ...

hlevel

我已经阅读了SO问题:paste two data.table columns,这使我尝试使用do.call - 但我不知道如何处理分隔符的更改或如果key_level是如何返回NA低于要求的水平。我原以为get_level_x_key = function(dt, hlevel) { my_columns = paste0("level_", 1:4) my_first_max = min(hlevel, 2) # first part of key is delimited with hypthens my_dt[, #do.call(paste, c( do.call(paste, c(.SD[key_level >= hlevel, my_columns[1:my_first_max], with = FALSE], list(sep="."))),] #safe.ifelse(hlevel > 2, do.call(paste, c(.SD[, my_columns[2:hlevel], with = FALSE], list(sep="-"))), NA)), list(sep="-")] #)] } get_level_x_key(my_dt, 3) # Gives: [1] "H111-a12" "H111-a12" "H111-b12" "H222-c12" 函数可能会有用......但我有点失落。

我很感激任何指导,我对如何解决这个问题感到有些困惑。谢谢!

1 个答案:

答案 0 :(得分:1)

也许试试这个:

weave = function(a, b) {
  # return c(a[1], b[1], a[2], b[2], ..., a[N])
  stopifnot(length(b) >= length(a) - 1)
  b = c(b[1:(length(a) - 1)], list(NULL))
  c(rbind(as.list(a), b))
}

f = function(hlevel) {
    my_dt[, ifelse(key_level < hlevel,
                   NA,
                   do.call(paste0, weave(.SD[, 1:hlevel], c('-','-','.','.'))))]
}

f(3)
# [1] "H111-a12-B9" "H111-a12-B2" "H111-b12-G1" NA "H222-c12-F4" NA

f(5)
# [1] "H111-a12-B9.11.A" NA "H111-b12-G1.55.B" NA NA NA