Спасибо вам обоим за элегантные решения! Оба решения сработали для меня, но только решение melt() и обратное соединение работали для таблицы data.table с датами вместо числовых значений.

ИЗМЕНИТЬ

Я реализовал предложенное решение data.table путем плавления и объединения с полученными результатами от Вимпеля, поскольку его / ее решение также работает с датами, хранящимися в столбцах даты, а не с исходными данными игрушки, которые были целыми числами. значения.

Я предпочел удобочитаемость решения Peace Wang, хотя при использовании data.table assignments и IMO это гораздо более четкий синтаксис, чем решение melt(), однако (по крайней мере, для меня) оно не работает с столбцы типа дата.

Сравнение обоих решений для числовых / целочисленных данных показало, что решение melt() является явным победителем.


ИЗМЕНИТЬ 2 Чтобы воспроизвести NA-значения посредством преобразования, которое я получаю, если я реализую решение, предложенное Peace Wang, см. Ниже исправленную версию входной таблицы 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 

Я определил минимальное значение каждой строки в моей таблице данных dt следующим образом:

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

Все идет нормально. Теперь я хочу добавить новый столбец Min_Date с указанием соответствующего имени столбца (также известного как дата в моем примере) найденного минимального значения для каждой строки, чтобы наконец получить что-то вроде этого:

  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]

Был бы признателен за любой указатель!

0
aimbotter21 1 Мар 2021 в 02:03

2 ответа

Лучший ответ

Вот еще один 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
1
Wimpel 1 Мар 2021 в 18:59

Следующий код может работать.

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.

1
Peace Wang 1 Мар 2021 в 14:02