簡體   English   中英

R - data.table 將作為行的最小值的列的名稱作為值分配給新列

[英]R - data.table assign the name of a column that is the minium of a row as value to new column

感謝你們提出了優雅的解決方案,這兩種解決方案都對我有用,但只有melt()和 back-join 解決方案適用於 data.table 的日期而不是數值。

編輯

通過熔化並與從 Wimpel 獲得的結果重新結合來實施建議的 data.table 解決方案,因為他/她的解決方案也適用於存儲在日期列中的日期,而不是所有 integer 值的初始玩具數據。

我更喜歡 Peace Wang 解決方案的可讀性,盡管使用data.table 分配和 IMO,它的語法比melt()解決方案更清晰,但是(至少對我而言),它不適用於日期類型的列。

對數值/整數數據的兩種解決方案進行基准測試后, melt()解決方案顯然是贏家。


編輯 2如果我實施 Peace Wang 提出的解決方案,要通過轉換復制 NA 值,請參閱下面的輸入 data.table 的更正版本。

我有這樣的事情:將患者記錄列表與在不同日期進行的測量進行圖像化。 日期列的名稱將是“2020-12-15”/“2021-01-15”等。

 ID   Date_1       Date_2      Date_3   
  1   1990-01-01   1990-02-01  1990-03-01      
  2   1990-01-01   1990-02-01  1990-03-01       
  3   1990-01-01   1982-02-01  1990-03-01 

我已經確定了 data.table dt中每一行的最小值,如下所示:

dt <- dt[, Min := do.call(pmin, c(.SD, list(na.rm = TRUE))), .SDcols = -(1)]

到目前為止,一切都很好。 現在我想添加一個新的 col Min_Date ,說明每行找到的最小值的相應 col 名稱(在我的示例中為日期),以最終得到這樣的結果:

  ID   Date_1       Date_2      Date_3        Min        Min_Date
  1    1990-01-01   1990-02-01  1990-03-01   1990-01-01  Date_1
  2    1990-01-01   1990-02-01  1990-03-01   1990-01-01  Date_1
  3    1990-01-01   1982-02-01  1990-03-01   1982-02-01  Date_2

我嘗試了以下變化:

dt <- dt[, Min_Date := do.call(which.pmin, c(.SD, list(na.rm = TRUE))),
                           .SDcols = (2:4)]

然后嘗試用 col 索引做某事。 真的不知道我的方式.I還沒有,但是當我在這些方面使用時,我無法讓它工作:

exclusions.dt[exclusions.dt[, .I[which.min(.SD)], ISSUE_ID, .SDcols = (2:6)]$V1]

將不勝感激任何指針!

以下代碼可以工作。

dt <- fread("
             ID   Date_1   Date_2   Date_3
  1    100      200      300
  2    100      500      300
  3    200      150      400
")
dt[, `:=`(Min = do.call(pmin, c(.SD, list(na.rm = TRUE))),
          date_min = colnames(.SD)[apply(.SD, 1, which.min)]
         ), 
   .SDcols = -1]

如果您收到NAs警告,也許您可以先嘗試刷新dt

這是另一種data.table方法

#sample data
library( data.table )
DT <- fread("ID   Date_1   Date_2   Date_3   
  1    100      200      300      
  2    100      500      300      
  3    200      150      400    ")

#melt to long format and get rows with minimum value by ID
DT.min <- melt( DT, id.vars = "ID" )[ , .SD[ which.min(value) ], by = ID]
#    ID variable value
# 1:  1   Date_1   100
# 2:  2   Date_1   100
# 3:  3   Date_2   150

#join back to DT
DT[ DT.min, `:=`( Min = i.value, Min_Date = i.variable ), on = .(ID)][]
#    ID Date_1 Date_2 Date_3 Min Min_Date
# 1:  1    100    200    300 100   Date_1
# 2:  2    100    500    300 100   Date_1
# 3:  3    200    150    400 150   Date_2

暫無
暫無

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

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