質問

私はこのように見えるデータフレーム「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.

このデータフレームに、対応するリターンの密度値を示す新しい列を追加したいと思います。私は試した:

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

しかし、それはうまくいきませんでした。各行に「関数」を適用するのは本当に困難です。しかし、density()を使用するのではなく、それを行う別の方法もあるかもしれませんか?

私が本質的にやりたいのは、密度()から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() 補間する xy 返された密度のコンポーネントですが、私は好みます 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 のベクトルに 1計算を続行するのに十分な長さのs リサイクル Rスピーキングで。

時には、ループを使用してオブジェクトを反復する必要がある場合があります。 s|l|t|apply() 家族ですが、ほとんどの場合、データのベクトル全体に対して一度に機能する関数が見つかります。これは、他のプログラミング言語よりもRの利点の1つですが、頭を引く必要があります ベクトル化 モード。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top