【问题标题】:Extract one column value based on the first instance value in another column根据另一列中的第一个实例值提取一个列值
【发布时间】:2016-10-03 15:07:48
【问题描述】:

我有一个下面给出的数据表以及两个场景的 dput。

DT1:

  date      item id
 1: 2016-09-05  view  1
 2: 2016-09-05  view  1
 3: 2016-09-05  view  1
 4: 2016-09-06    pv  1
 5: 2016-09-06    pv  1
 6: 2016-09-06    pv  1
 7: 2016-09-06 check  1
 8: 2016-09-06 check  1
 9: 2016-09-06 check  1
10: 2016-09-06 check  1

输入1:

DT = setDT(structure(list(date = structure(c(17049, 17049, 17049, 17050, 
17050, 17050, 17050, 17050, 17050, 17050), class = "Date"), item = c("view", 
"view", "view", "pv", "pv", "pv", "check", "check", "check", 
"check"), id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("date", 
"item", "id"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame")))

DT2:

date     item id
 1: 2016-09-05  view  1
 2: 2016-09-05  view  1
 3: 2016-09-05  view  1
 4: 2016-09-08    pv  1
 5: 2016-09-06   pv1  1
 6: 2016-09-06   pv2  1
 7: 2016-09-06 check  1
 8: 2016-09-06 check  1
 9: 2016-09-06 check  1
10: 2016-09-06 check  1

输入2:

structure(list(date = structure(c(17049, 17049, 17049, 17050, 
17050, 17050, 17050, 17050, 17050, 17050), class = "Date"), item = c("view", 
"view", "view", "pv", "pv1", "pv2", "check", "check", "check", 
"check"), id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("date", 
"item", "id"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x0000000000210788>)

我正在尝试在“项目”列中查找第一次出现 pv 的日期并提取该条目的相应日期,然后通过 id 提取“项目”中第一次出现检查的日期,取天数差异并存储在新变量中。

如果有多个条件需要我们检查“pv”,该怎么办。例如,如果“pv”不在列表中,则可以检查“pv1”或“pv2”。这个想法是第一次出现。因此,如果存在 pv、pv1 和 pv2 但 pv2 先出现,则应采用 pv2 对应的日期。类似地,项目列中可能仅存在“pv2”或“pv1”或“pv”。我们如何执行检查以从三种可能性中取出第一次出现并提取日期。有什么想法吗?

寻找有关使用数据表或%&gt;%的最少代码完成它的想法和建议。

【问题讨论】:

    标签: r data.table dplyr transform data-manipulation


    【解决方案1】:

    如果'dt'是'data.table'对象,按'id'分组后,我们得到'pv'(which.max(item=="pv"))和'check'第一次出现的索引,子集'date'基于该索引,将其减去并将 (:=) 分配给新变量“Diff”。

    dt[, Diff := date[which.max(item == "pv")]- date[which.max(item =="check")], by = id]
    

    或者代替which.max,使用match获取索引

    dt[, Diff := date[match("pv", item)] - date[match("check", item)], by = id]
    

    注意 1:假设所有 'id' 至少有一个 'pv' 和 'check'。

    注意2:如果我们需要特定单位的差异,请使用difftime并指定units

    【讨论】:

    • ndays &lt;- as.numeric(diff(as.Date(c(dt[item=="pv"][1]$date, dt[item=="check"][1]$date) ))) 只是为了演示如何使用difftime
    • @akrun - 我们是否也可以在上面的代码中包含一个检查或单独检查项目为“检查”的日期是否大于项目为“pv”的日期?
    • @nathanesau difftime 参数可能是 difftime(date[which.max(item == "pv")], date[which.max(item == "check")], unit = "day")
    • @syebill 是的,你可以这样做,也许,dt[, c("Diff", "DateCheck") := {v1 &lt;- date[match("pv", item)] - date[match("check", item)]; v2 &lt;- v1 &lt; 0; list(v1, v2) }, by = id]
    • 啊,好吧,您在逻辑上使用 which.max,这让我感到困惑,并且显然依赖于按日期排序以及该逻辑中存在一些 TRUE 值(如在你的注释1)。现在这对我来说很有意义,尽管像 DT[, {mins = tapply(date, item, min); mins["pv"] - mins["check"]}, by=id] 这样的东西对我来说更容易理解。作为旁注,我完全不清楚当假设被违反时会发生什么行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2021-11-08
    • 2015-08-03
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多