簡體   English   中英

根據data.table中特定列的多個條件標記行

[英]Flag rows based on multiple conditions on specific columns in data.table

我有一個data.table,在特定年份有多列“性能”和一個名為“預期性能”的列。 我想創建一個名為FLAG的新列,它將根據以下兩個條件指示標記為手動審閱的行:

  1. 任何性能列都具有負值
  2. 預期的性能列與任何性能列的不同之處超過50%。

一個類似於我的模擬data.table:

library(data.table)
dt <- data.table(Id = c("N23", "N34", "N11", "N65", "N55", "N78", "N88"),
                 Name = c("ABCD", "ACBD", "ACCD", "ADBN", "ADDD", "DBCA", "CBDA"),
                 Type = c("T", "B", "B", "T", "T", "B", "B"),
                 Sold = c(500, 300, 350, 500, 350, 400, 450),
                 Baseline = c(2000, 2100, 2000, 1500, 1890, 1900, 2000),
                 Perf_2016 = c(-200, 420, 800, 900, -10, 75, 400),
                 Perf_2017 = c(500, 300, -20, 700, 50, 80, 370),
                 Perf_2018 = c(1000, 400, 600, 800, 40, 500, 300),
                 ExpPerf_2019 = c(1500, 380, 500, 850, 30, 400, 350))
dt

Id Name Type Sold Baseline Perf_2016 Perf_2017 Perf_2018 ExpPerf_2019
N23 ABCD T   500  2000     -200      500       1000      1500
N34 ACBD B   300  2100     420       300       400       380
N11 ACCD B   350  2000     800       -20       600       500
N65 ADBN T   500  1500     900       700       800       850
N55 ADDD T   350  1890     -10       50        40        30
N78 DBCA B   400  1900     75        80        500       400
N88 CBDA B   450  2000     400       370       300       350

對於此data.table,所需的輸出將添加FLAG列,如下所示:

    Id Name Type Sold Baseline Perf_2016 Perf_2017 Perf_2018 ExpPerf_2019  FLAG
1: N23 ABCD    T  500     2000      -200       500      1000         1500  TRUE
2: N34 ACBD    B  300     2100       420       300       400          380 FALSE
3: N11 ACCD    B  350     2000       800       -20       600          500  TRUE
4: N65 ADBN    T  500     1500       900       700       800          850 FALSE
5: N55 ADDD    T  350     1890       -10        50        40           30  TRUE
6: N78 DBCA    B  400     1900        75        80       500          400  TRUE
7: N88 CBDA    B  450     2000       400       370       300          350 FALSE
  1. 任何性能列都具有負值
  2. 預期的性能列與任何性能列的不同之處超過50%。

換句話說,這些列有共同的最小和最大界限:

  • min是max(0,ExpPerf * 0.5)
  • 最大值是ExpPerf * 1.5

所以...

dt[, v := !Reduce(`&`, 
  lapply(.SD, between, pmax(0, ExpPerf_2019*0.5), ExpPerf_2019*1.5)
), .SDcols=grep("^Perf_", names(dt), value=TRUE)]

    Id Name Type Sold Baseline Perf_2016 Perf_2017 Perf_2018 ExpPerf_2019     v
1: N23 ABCD    T  500     2000      -200       500      1000         1500  TRUE
2: N34 ACBD    B  300     2100       420       300       400          380 FALSE
3: N11 ACCD    B  350     2000       800       -20       600          500  TRUE
4: N65 ADBN    T  500     1500       900       700       800          850 FALSE
5: N55 ADDD    T  350     1890       -10        50        40           30  TRUE
6: N78 DBCA    B  400     1900        75        80       500          400  TRUE
7: N88 CBDA    B  450     2000       400       370       300          350 FALSE

這個怎么運作:

  • between如果列位於min和max之間的檢查
  • lapply將檢查應用於每一列,返回一個列表
  • 使用& Reduce並檢查所有列是否滿足條件
  • ! 否定結果,因此我們確定至少有一列失敗的情況

between&! 是矢量化運算符,所以我們最終得到一個結果向量,每行一個。 我可能會在magrittr中編寫這個序列,所以步驟更容易理解:

library(magrittr)

dt[, v := .SD %>% 
  lapply(between, pmax(0, ExpPerf_2019*0.5), ExpPerf_2019*1.5) %>%
  Reduce(f=`&`) %>%
  not
, .SDcols=grep("^Perf_", names(dt), value=TRUE)]

not重拍! ,為方便起見,由magrittr提供。

.SD是在DT[i, j, by]j部分內部操作的數據子集的特殊符號。 在這種情況下,沒有iby ,因此只有.SDcols是子集(用於選擇感興趣的列)。

評論

  • 如果OP選擇以長格式格式化數據,則代碼將更簡單。
  • 我的答案使用與Gilean相同的步驟,但是是矢量化而不是每行計算。

您可以使用以下代碼檢查兩個條件:

dt[, FLAG := any(.SD < 0 | .SD < ExpPerf_2019 - .5*ExpPerf_2019 | .SD > ExpPerf_2019 + .5*ExpPerf_2019),
   by = Id,
   .SDcols = grep("^Perf", colnames(dt), value = TRUE)
   ]

結果:

> dt
    Id Name Type Sold Baseline Perf_2016 Perf_2017 Perf_2018 ExpPerf_2019  FLAG
1: N23 ABCD    T  500     2000      -200       500      1000         1500  TRUE
2: N34 ACBD    B  300     2100       420       300       400          380 FALSE
3: N11 ACCD    B  350     2000       800       -20       600          500  TRUE
4: N65 ADBN    T  500     1500       900       700       800          850 FALSE
5: N55 ADDD    T  350     1890       -10        50        40           30  TRUE
6: N78 DBCA    B  400     1900        75        80       500          400  TRUE
7: N88 CBDA    B  450     2000       400       370       300          350 FALSE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM