Изменение значения в ранге при заданном условии

#r #dplyr #tidyr #tidyquant

#r #dplyr #tidyr #tidyquant

Вопрос:

Я пытаюсь преобразовать таблицу акций, ранжированных по их возврату, в матрицу значений, которые будут вводиться в PerformanceAnalytics::ReturnPortfolio качестве весов акций в портфеле.

Что я специально ищу, так это преобразовать значение рейтинга 33% лучших акций в 1, 33% акций с худшими показателями в -1, а остальные в 0.

Это исходный код, в котором я просто беру лучшие акции и меняю их ранжированное значение на 1:

 asset_ranking <- db_Momentum %>%
  dplyr::select(-date) %>%
  as.matrix() %>%
  rowRanks(ties.method = "min") %>%
  as.data.frame() %>%
  dplyr::mutate(date = db_Momentum$date) %>%
  dplyr::select(date, everything()) %>%
  purrr::set_names(c("date", tickets)) %>%
  as_tibble()

# Analyzing Sector Selection
asset_selection <- asset_ranking %>%
  mutate_if(is.numeric, ~   ( . > (length(tickets) - n_assets_buy))) %>%
  dplyr::select(-date)
 

Это пример того, на что это похоже сейчас:

AAPL IBM KO T TLT ШПИОН
1 2 3 4 6 5
2 1 3 5 4 6
1 4 2 5 3 6
6 4 5 2 1 3

И это то, что я хотел бы, чтобы это было:

AAPL IBM KO T TLT ШПИОН
1 1 0 0 -1 -1
1 1 0 -1 0 -1
1 0 1 -1 0 -1
-1 0 -1 1 1 0

Ответ №1:

Мы могли бы перебирать строки с apply помощью и MARGIN = 1 , получать quantile с probs .33 помощью и .67 , передавать это как breaks в cut , преобразовывать в integer и использовать этот индекс для замены значений на 1, 0, -1

 asset_selection[] <- t(apply(asset_selection, 1, function(x)
   c(1, 0, -1)[as.integer(cut(x, c(-Inf, quantile(x, c(.33, .67)), Inf)))]))
 

-вывод

 asset_selection
#  AAPL IBM KO  T TLT SPY
#1    1   1  0  0  -1  -1
#2    1   1  0 -1   0  -1
#3    1   0  1 -1   0  -1
#4   -1   0 -1  1   1   0
 

данные

 asset_selection <- structure(list(AAPL = c(1, 2, 1, 6), 
      IBM = c(2, 1, 4, 4), KO = c(3, 
 3, 2, 5), T = c(4, 5, 5, 2), TLT = c(6, 4, 3, 1), SPY = c(5, 
6, 6, 3)), class = "data.frame", row.names = c(NA, -4L))
 

Комментарии:

1. Это не сработало бы с большим количеством запасов. Или как бы вы сделали это, например, для акций 9?

2. @ChorMachine Если у вас есть 9 акций, какое значение будет заменено. Я предполагаю, что на основе логики может быть 8 - asset_ranking ?

3. Как я уже говорил в вопросе, цель состоит в том, чтобы преобразовать 33% наиболее эффективных акций в 1, 33% худших в -1, а остальные 33% в 0. Что в случае списка из 12 акций будет равно 4 на категорию.

4. @ChorMachine Пожалуйста, обновите свой пример ввода более общим примером и его ожидаемым результатом. Когда есть простой случай, возникает соблазн дать простое исправление

5. @ChorMachine Я не заметил, что вы изменили данные. Я изменил код, пожалуйста, проверьте