Как вывести 6-е худшее значение на основе 2 критериев и вставить результаты в отдельный столбец? - PullRequest
0 голосов
/ 26 июня 2018

надеялся, что кто-то может помочь.

Я пытаюсь добавить другой столбец: 6th Worst. Что я хочу сделать, так это получить 6-й худший результат y, основанный на указанных критериях: Date.

Вот пример моего df:

Key     Date                     y   x1   x2   x3
   1    1/10/2018 12:00:00 AM    2   3    2    5
   1    1/11/2018 12:00:00 AM    3   5    7    2
   1    1/12/2018 12:00:00 AM    5   7    4    7 
   1    1/13/2018 12:00:00 AM    7   2    7    6
   2    1/10/2018 12:00:00 AM    2   6    3    8
   2    1/11/2018 12:00:00 AM    3   7    7    3
   2    1/12/2018 12:00:00 AM    3   2    3    4
   2    1/13/2018 12:00:00 AM    7   6    2    7
   3    1/10/2018 12:00:00 AM    2   3    2    5
   3    1/11/2018 12:00:00 AM    3   5    7    2
   3    1/12/2018 12:00:00 AM    5   7    4    7 
   3    1/13/2018 12:00:00 AM    7   2    7    6
   3    1/10/2018 12:00:00 AM    2   6    3    8
   3    1/11/2018 12:00:00 AM    3   7    7    3
   3    1/12/2018 12:00:00 AM    3   2    3    4
   3    1/13/2018 12:00:00 AM    7   6    2    7
   4    1/10/2018 12:00:00 AM    2   3    2    5
   4    1/11/2018 12:00:00 AM    3   5    7    2
   4    1/12/2018 12:00:00 AM    5   7    4    7 
   4    1/13/2018 12:00:00 AM    7   2    7    6
   4    1/10/2018 12:00:00 AM    2   6    3    8
   4    1/11/2018 12:00:00 AM    3   7    7    3
   5    1/12/2018 12:00:00 AM    3   2    3    4
   5    1/13/2018 12:00:00 AM    7   6    2    7
   5    1/10/2018 12:00:00 AM    2   3    2    5
   5    1/11/2018 12:00:00 AM    3   5    7    2
   5    1/12/2018 12:00:00 AM    5   7    4    7 
   5    1/13/2018 12:00:00 AM    7   2    7    6
   6    1/10/2018 12:00:00 AM    2   6    3    8
   6    1/11/2018 12:00:00 AM    3   7    7    3
   6    1/12/2018 12:00:00 AM    3   2    3    4
   6    1/13/2018 12:00:00 AM    7   6    2    7

Итак, для 1/10/2018 3. Таким образом, набор данных будет выглядеть так:

 Key        Date                     y   x1   x2   x3 6th worst   
       1    1/10/2018 12:00:00 AM    2   3    2    5  3
       1    1/11/2018 12:00:00 AM    3   5    7    2  ... (would have values)
       1    1/12/2018 12:00:00 AM    5   7    4    7  ... (would have values)
       1    1/13/2018 12:00:00 AM    7   2    7    6  ... (would have values)
       2    1/10/2018 12:00:00 AM    2   6    3    8  3
       2    1/11/2018 12:00:00 AM    3   7    7    3  etc.
       2    1/12/2018 12:00:00 AM    3   2    3    4
       2    1/13/2018 12:00:00 AM    7   6    2    7
       3    1/10/2018 12:00:00 AM    2   3    2    5
       3    1/11/2018 12:00:00 AM    3   5    7    2
       3    1/12/2018 12:00:00 AM    5   7    4    7 
       3    1/13/2018 12:00:00 AM    7   2    7    6
       3    1/10/2018 12:00:00 AM    2   6    3    8
       3    1/11/2018 12:00:00 AM    3   7    7    3
       3    1/12/2018 12:00:00 AM    3   2    3    4
       3    1/13/2018 12:00:00 AM    7   6    2    7
       4    1/10/2018 12:00:00 AM    2   3    2    5
       4    1/11/2018 12:00:00 AM    3   5    7    2
       4    1/12/2018 12:00:00 AM    5   7    4    7 
       4    1/13/2018 12:00:00 AM    7   2    7    6
       4    1/10/2018 12:00:00 AM    2   6    3    8
       4    1/11/2018 12:00:00 AM    3   7    7    3
       5    1/12/2018 12:00:00 AM    3   2    3    4
       5    1/13/2018 12:00:00 AM    7   6    2    7
       5    1/10/2018 12:00:00 AM    2   3    2    5
       5    1/11/2018 12:00:00 AM    3   5    7    2
       5    1/12/2018 12:00:00 AM    5   7    4    7 
       5    1/13/2018 12:00:00 AM    7   2    7    6
       6    1/10/2018 12:00:00 AM    2   6    3    8
       6    1/11/2018 12:00:00 AM    3   7    7    3
       6    1/12/2018 12:00:00 AM    3   2    3    4
       6    1/13/2018 12:00:00 AM    7   6    2    7

Вот что у меня есть:

# для получения 6-го наихудшего значения из набора данных

n=length(df$y)

df$`6th Worst`= df$`6th Worst`= "-"

df[1,3] = round(-sort(subset(df,c(unique(Date), "y")), partial=n-5)[n-5], digits = 2)

Я получаю следующую ошибку:

    Error in subset.data.frame(reg_predict, unique(reg_predict2$Date)) : 
  'subset' must be logical

Edit: вопрос отличается от дублированного отмеченного вопроса в нескольких отношениях. Особенно в том, что мне нужен условный 6-й худший сценарий, а не просто худший / лучший сценарий.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Опцией с dplyr и sort может быть:

Примечание: Можно преобразовать столбец Date в формат POSIXct перед группировкой, но я не заметил никаких преимуществ как таковых.

library(dplyr)

df %>% group_by(Date) %>% 
  mutate(Worst6th = sort(y)[6])

# A tibble: 32 x 7
# Groups: Date [4]
    Key Date                      y    x1    x2    x3 Worst6th
  <int> <chr>                 <int> <int> <int> <int>    <int>
1     1 1/10/2018 12:00:00 AM     2     3     2     5        2
2     1 1/11/2018 12:00:00 AM     3     5     7     2        3
3     1 1/12/2018 12:00:00 AM     5     7     4     7        5
4     1 1/13/2018 12:00:00 AM     7     2     7     6        7
5     2 1/10/2018 12:00:00 AM     2     6     3     8        2
6     2 1/11/2018 12:00:00 AM     3     7     7     3        3
7     2 1/12/2018 12:00:00 AM     3     2     3     4        5
8     2 1/13/2018 12:00:00 AM     7     6     2     7        7
9     3 1/10/2018 12:00:00 AM     2     3     2     5        2
10     3 1/11/2018 12:00:00 AM     3     5     7     2        3
# ... with 22 more rows      

Данные:

df <- read.table(text="
Key     Date                     y   x1   x2   x3
1    '1/10/2018 12:00:00 AM'    2   3    2    5
1    '1/11/2018 12:00:00 AM'    3   5    7    2
1    '1/12/2018 12:00:00 AM'    5   7    4    7 
1    '1/13/2018 12:00:00 AM'    7   2    7    6
2    '1/10/2018 12:00:00 AM'    2   6    3    8
2    '1/11/2018 12:00:00 AM'    3   7    7    3
2    '1/12/2018 12:00:00 AM'    3   2    3    4
2    '1/13/2018 12:00:00 AM'    7   6    2    7
3    '1/10/2018 12:00:00 AM'    2   3    2    5
3    '1/11/2018 12:00:00 AM'    3   5    7    2
3    '1/12/2018 12:00:00 AM'    5   7    4    7 
3    '1/13/2018 12:00:00 AM'    7   2    7    6
3    '1/10/2018 12:00:00 AM'    2   6    3    8
3    '1/11/2018 12:00:00 AM'    3   7    7    3
3    '1/12/2018 12:00:00 AM'    3   2    3    4
3    '1/13/2018 12:00:00 AM'    7   6    2    7
4    '1/10/2018 12:00:00 AM'    2   3    2    5
4    '1/11/2018 12:00:00 AM'    3   5    7    2
4    '1/12/2018 12:00:00 AM'    5   7    4    7 
4    '1/13/2018 12:00:00 AM'    7   2    7    6
4    '1/10/2018 12:00:00 AM'    2   6    3    8
4    '1/11/2018 12:00:00 AM'    3   7    7    3
5    '1/12/2018 12:00:00 AM'    3   2    3    4
5    '1/13/2018 12:00:00 AM'    7   6    2    7
5    '1/10/2018 12:00:00 AM'    2   3    2    5
5    '1/11/2018 12:00:00 AM'    3   5    7    2
5    '1/12/2018 12:00:00 AM'    5   7    4    7 
5    '1/13/2018 12:00:00 AM'    7   2    7    6
6    '1/10/2018 12:00:00 AM'    2   6    3    8
6    '1/11/2018 12:00:00 AM'    3   7    7    3
6    '1/12/2018 12:00:00 AM'    3   2    3    4
6    '1/13/2018 12:00:00 AM'    7   6    2    7",
header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 26 июня 2018

Опция, использующая пакет data.table:

library(data.table)

## Generate data
set.seed(1)
RowCount <- 100
DT <- data.table(Date = Sys.Date() + sample.int(3,RowCount,TRUE),
                 y = sample.int(100,RowCount,TRUE))

## Sort by y
setkey(DT,y)

## Too much to unpack here in inline commments, will expand further down
SixthWorst_DT <- DT[DT[,.I[6],by = .(Date)]$V1,.(Sixth_Worst = y), keyby = .(Date)]

print(SixthWorst_DT)

#    Date       Sixth_Worst
# 1: 2018-06-27          42
# 2: 2018-06-28          11
# 3: 2018-06-29          22

## Set DT Key to be date for update-join
setkey(DT,Date)
## Temporarily join `SixthWorst_DT` to `DT` (without making a full copy)
## and then create a column in `DT` based on the column `Sixth_Worst` in `SixthWorst_DT`
DT[SixthWorst_DT, Sixth_Worst := i.Sixth_Worst]

## Results
head(DT)

#    Date        y Sixth_Worst
# 1: 2018-06-27 18          42
# 2: 2018-06-27 18          42
# 3: 2018-06-27 19          42
# 4: 2018-06-27 19          42
# 5: 2018-06-27 39          42
# 6: 2018-06-27 42          42

Реальное содержание операции - одна строка:

SixthWorst_DT <- DT[DT[,.I[6],by = .(Date)]$V1,.(Sixth_Worst = y), keyby = .(Date)]

  • DT[,.I[6],by = .(Date)] использует специальный символ .I, чтобы извлечь номер 6-й строки для каждой даты
  • добавленный $V1 извлекает вектор из этих номеров строк
  • Затем DT задается с помощью этого вектора
  • Затем DT набирается (и неявно упорядочивается) и группируется по Date для создания сводной таблицы с новым столбцом Sixth_Worst на основе y

Чтобы действительно понять, что происходит, я бы порекомендовал выполнить следующие утверждения.

  • DT[,.I[6],by = .(Date)]
  • DT[,.I[6],by = .(Date)]$V1
  • DT[DT[,.I[6],by = .(Date)]$V1]
  • DT[DT[,.I[6],by = .(Date)]$V1,.(Sixth_Worst = y), keyby = .(Date)]
...