Значение плотности для каждого возврата

StackOverflow https://stackoverflow.com/questions/4488888

  •  11-10-2019
  •  | 
  •  

Вопрос

У меня есть данные о данных "foo"

Date       Return
1998-01-01  0.02
1998-01-02  0.04
1998-01-03 -0.02
1998-01-04 -0.01
1998-01-05  0.02
...
1998-02-01  0.1
1998-02-02 -0.2
1998-02-03 -0.1
etc.

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

foo$density <- for(i in 1:length(foo$Return)) density(foo$Return, 
from = foo$Return[i], to = foo$Return[i], n = 1)$y

Но это не сработало. У меня действительно трудно применять «функцию» к каждой строке. Но, может быть, есть и другой способ сделать это, не использовать плотность ()?

По сути, я хотел бы сделать, так это извлечь значения приспособленных плотности от плотности () до возврата в Foo. Если я просто сделаю график (плотность (foo $ return)), он даст мне кривую, однако я хотел бы иметь значения плотности, прикрепленные к возврату.

@Joris:

foo$density <- density(foo$Return, n=nrow(foo$Return))$y 

Тем не менее, вычисляет что -то, кажется, возвращает неправильные значения плотности.

Спасибо, что помогли мне! Дани

Это было полезно?

Решение

Подумайте, забудьте о функции плотности, я внезапно понял, что вы хотите сделать. Большинство функций плотности возвращают сетку, поэтому не дайте вам оценку в точных точках. Если вы этого хотите, вы можете использовать sm упаковка:

require(sm)
foo <- data.frame(Return=rpois(100,5))
foo$density <- sm.density(foo$Return,eval.points=foo$Return)$estimate
# the plot
id <- order(foo$Return)
hist(foo$Return,freq=F)
lines(foo$Return[id],foo$density[id],col="red")

Если количество разных значений не так большое, вы можете использовать Ave ():

foo$counts <- ave(foo$Return,foo$Return,FUN=length)

Если цель состоит в участок Функция плотности, нет необходимости рассчитывать, как вы. Просто используйте

plot(density(foo$Return))

Или, чтобы добавить гистограмму внизу (не учитывайте вариант freq=F)

hist(foo$Return,freq=F)
lines(density(foo$Return),col="red")

Другие советы

Альтернатива sm.density это оценить плотность в более тонкой сетке, чем по умолчанию, и использовать approx или же approxfun дать интерполированные значения плотности в Returns ты хочешь. Вот пример с фиктивными данными:

set.seed(1)
foo <- data.frame(Date = seq(as.Date("2010-01-01"), as.Date("2010-12-31"),
                             by = "days"),
                  Returns = rnorm(365))
head(foo)
## compute the density, on fin grid (512*8 points)
dens <- with(foo, density(Returns, n = 512 * 8))

На этом этапе мы могли бы использовать approx() чтобы интерполировать x а также y компоненты возвращенной плотности, но я предпочитаю approxfun() что делает то же самое, но возвращает функцию, которую мы затем можем использовать для выполнения интерполяции. Сначала генерируйте функцию интерполяции:

## x and y are components of dens, see str(dens)
BAR <- with(dens, approxfun(x = x, y = y))

Теперь вы можете использовать BAR() Чтобы вернуть интерполированную плотность в любой точке, например, для первого Returns:

> with(foo, BAR(Returns[1]))
[1] 0.3268715

Чтобы закончить пример, добавьте плотность для каждого данных в Returns:

> foo <- within(foo, Density <- BAR(Returns))
> head(foo)
        Date    Returns   Density
1 2010-01-01 -0.6264538 0.3268715
2 2010-01-02  0.1836433 0.3707068
3 2010-01-03 -0.8356286 0.2437966
4 2010-01-04  1.5952808 0.1228251
5 2010-01-05  0.3295078 0.3585224
6 2010-01-06 -0.8204684 0.2490127

Чтобы увидеть, насколько хорошо работает интерполяция, мы можем построить плотность и интерполированную версию и сравнить. Обратите внимание, что мы должны сортировать Returns Потому что для достижения желаемого эффекта, мы хотим, lines нужно увидеть данные в увеличиваясь заказ:

plot(dens)
with(foo, lines(sort(Returns), BAR(sort(Returns)), col = "red"))

Что дает что -то вроде этого:Density (in black) and interpolated version (in red)

До тех пор, пока плотность оценивается в достаточной степени набор точек (512*8 в приведенном выше примере), у вас не должно быть никаких проблем, и им будет трудно сказать разницу между интерполированной версией и реальной вещью. Если у вас есть «пробелы» в значениях ваших Returns тогда вы можете найти это, как lines() Просто присоединяется к точкам, которые вы просите, чтобы построить, что прямые сегменты линии могут не следовать плотности черной в местах пробелов. Это всего лишь артефакт пробелов и как lines() Работает, а не проблема с интерполяцией.

Если мы проигнорируем density Проблема, на которую @joris опытные ответы, вы, похоже, не понимали, как настроить петлю. То, что вы возвращаетесь из петли, - это значение NULL. Анкет Это значение, которое вставляется в foo$density И это не сработает, потому что это NULL, что означает, что это пустой компонент, то есть он не существует, что касается R. Видеть ?'for' Для получения более подробной информации.

> bar <- for(i in 1:10) {
+     i + 1
+ }
> bar
NULL

> foo <- data.frame(A = 1:10, B = LETTERS[1:10])
> foo$density <- for(i in seq_len(nrow(foo))) {
+     i + 1
+ }
> head(foo) ## No `density`
  A B
1 1 A
2 2 B
3 3 C
4 4 D
5 5 E
6 6 F

Если вы хотите вставить возвращаемое значение для каждой итерации цикла, вы должны выполнить задание внутри Цикл, и это означает, что вы должны предварительно выделять место для хранения, прежде чем ввести цикл, например, вышеуказанный цикл, если мы хотим иметь i + 1 за i В 1, ..., 10, мы могли бы сделать это:

> bar <- numeric(length = 10)
> for(i in seq_along(bar)) {
+     bar[i] <- i + 1
+ }
> bar
 [1]  2  3  4  5  6  7  8  9 10 11

Конечно, вы не будете делать такого расчета, как это с помощью цикла, потому что R векторен и будет работать с векторами чисел, а не с необходимостью кодировать каждый элемент вычисления по элементу, как вы могли бы в C или других языках программирования.

> bar <- 1:10 + 1
> bar
 [1]  2  3  4  5  6  7  8  9 10 11

Обратите внимание, что R повернулся 1 в вектор 1S достаточной длины, чтобы позволить вычислению продолжаться, что -то, что известно как переработка в R-Speak.

Иногда вам может понадобиться итерация над объектом с петлей или использовать один из s|l|t|apply() Семья, но чаще всего вы найдете функцию, которая работает для всего вектора данных за один раз. Это одно из преимуществ R по сравнению с другими языками программирования, но требует от вас, чтобы ввести свою голову в векторизован режим.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top