Проверьте, какие значения интервала находятся в пределах каждого дня, и создайте новую матрицу, содержащую информацию о том, какой интервал в R - PullRequest
0 голосов
/ 08 апреля 2020

Я работаю с набором данных, содержащим информацию о ценах более 700 криптовалют с периода 2014-01-01 по 2019-12-31, который называется price.daily

            Bitcoin     Ethereum    XRP      Bitcoin.SV    Stellar    ...
   ...
2018-01-01  13657.20    772.64      2.39     NA            0.480008
2018-01-02  14982.10    884.44      2.48     NA            0.564766
2018-01-03  15201.00    962.72      3.11     NA            0.896227
   ... 

I Затем для каждого дня вычислили квантили, используя sapply , как предложил другой вопрос, и это прекрасно работает

col.daily <- seq(1,length(price.daily$Bitcoin))
quantile.daily = sapply(col.daily, function(y) {quantile(x = unlist(price.daily[y,] ), seq(0,1, length=6),na.rm = TRUE )})
quantile.daily.t = t(quantile.daily)
rownames(quantile.daily.t) = rownames(price.daily)

Из которого я получаю число, из которого мои интервалы должны быть

             0%         20%         40%         60%         80%     100%
   ...
2018-01-01   2.60e-05   0.1681120   0.7189722   2.3060000   9.392   13657.20
2018-01-02   3.40e-05   0.1946376   0.7232178   2.4240000   10.092  14982.10
2018-01-03   3.80e-05   0.1982452   0.7771724   2.4820000   10.054  15201.00
   ...

То, что я тогда хочу сделать, это для каждого дня взять цену каждой криптовалюты, проверить, в каком интервале она находится, и создать новую матрицу, содержащую числа от 1 до 5 и NA, если данных нет. Должно получиться как

            Bitcoin   Ethereum    XRP     Bitcoin.SV    Stellar   ...
   ...
2018-01-01  5         5           4       NA            2
2018-01-02  5         5           4       NA            2
2018-01-03  5         5           4       NA            3
   ...

Я полагаю, что для этого я также мог бы использовать sapply ?

Образец моих данных, используя dput(head(price.daily)) для моих данных price.daily

structure(list(Bitcoin = c(771.4, 802.39, 818.72, 859.51, 933.53, 
953.29), Ethereum = c(NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_), XRP = c(0.026944, 0.028726, 0.027627, 0.028129, 
0.02523, 0.0257), Bitcoin.Cash = c(NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_), row.names = c("2014-01-01", 
"2014-01-02", "2014-01-03", "2014-01-04", "2014-01-05", "2014-01-06"
), class = "data.frame")

и для квантилей

structure(c(0.00044, 0.000353, 0.000303, 0.000301, 0.000271, 
0.00001, 0.0330034, 0.0319948, 0.0327684, 0.0318646, 0.0274614, 
0.0237276, 0.161692, 0.1793948, 0.163744, 0.1610448, 0.1579238, 
0.0728448, 3.014, 3.728, 3.85, 3.87, 3.814, 2.54200000000001, 
6.036, 7.578, 7.14, 7.434, 7.474, 7.188, 771.4, 802.39, 818.72, 
859.51, 933.53, 953.29), .Dim = c(6L, 6L), .Dimnames = list(c("2014-01-01", 
"2014-01-02", "2014-01-03", "2014-01-04", "2014-01-05", "2014-01-06"
), c("0%", "20%", "40%", "60%", "80%", "100%")))

1 Ответ

0 голосов
/ 09 апреля 2020

Функция findInterval делает именно то, что вам нужно. Единственная трудность возникает из-за применения его к правильным данным.

Простое решение с помощью al oop:

result_loop = price.daily
for (i in seq_len(nrow(price.daily))) {
  result_loop[i, ] = findInterval(price.daily[i, ], quantile.daily[i, ])
}

Альтернативное решение без использования al oop:

combined = cbind(price.daily, quantile.daily)
result_alternative = as.data.frame(t(apply(combined, 1, function(x) findInterval(x[1:ncol(price.daily)], x[(1 + ncol(price.daily)):ncol(combined)]))))
colnames(result_alternative) = colnames(price.daily)

Второе решение (вдохновленное этим ответом на аналогичный вопрос ) имеет некоторые дополнительные проблемы, такие как перегрузка памяти для переменной combined. Даже если бы это было не так, я все равно использовал бы первое решение. Может быть соблазнительно использовать языковые конструкции, чтобы избежать циклов, но это во многих случаях значительно затрудняет отладку и обслуживание.

В качестве примечания: результатом может быть матрица вместо фрейма данных, но так как price.daily (излишне) задается как фрейм данных, я выбрал тот же класс для результата.

...