0

私は関数を書くのが初めてで、どこから始めればよいのかよくわかりません。以下は、この例の m1 という名前のデータ フレームのサブセットです。データセットを調べて、長さと深さの情報を数値で抽出する関数を書きたいと思います。たとえば、数値 1 に遭遇した場合、長さと深さを取得し、それらを新しいデータ フレームまたはベクトルの最初の行に挿入します。数値が 2 の場合も同様です。

       length number depth
 [1,]    109      1    10
 [2,]    109      1    10
 [3,]    109      1    10
 [4,]    109      1    10
 [5,]    109      1    10
 [6,]    109      1    10
 [7,]    109      1    10
 [8,]    109      1    10
 [9,]    109      1    10
[10,]    109      1    10
[11,]    109      1    10
[12,]    109      1    10
[13,]    107      2    10
[14,]    107      2    10
[15,]    107      2    10
[16,]    107      2    10
[17,]    107      2    10
[18,]    107      2    10
[19,]    107      2    10
[20,]    107      2    10

ここでは、数値が 1 の場合に上記の出力を取得する関数を作成しようとしています。

length.fun=function(x)
{
  lengths=numeric()
  depth=numeric()
  if (x[2]==1)
  {
    lengths=x[1]
    depth=x[3]
  }
  return(cbind(depth,lengths))
}

length.fun(m1)

ただし、出力として得られるのはこれだけです。

length.fun(m1)
   depth lengths

どんな助けでも大歓迎です。ありがとう

4

3 に答える 3

3

編集:

あなたのコメントから、一意の行を取得したいことがわかりました。幸いなことに、これ専用の関数があります。

unique(m1)

#       length number depth
# [1,]     109      1    10
# [13,]    107      2    10

unique(m1)[,-2]2つの列のみが表示されます。as.data.frameマトリックスを data.frame に変換するために使用します。


m1行列です。行列は、次元属性を持つ単なるベクトルです。m1[2]ベクトルの 2 番目の値、つまり が得られます109。したがって、あなたのif条件はFALSEでありcbind、関数内のベクトルを空にします。

これはあなたが望むことをします:

m1[m1[,2]==1,c(1,3)]

R での行列のサブセット化について読む必要があります。

デバッグ機能を使用して、何が起こるかを調べることができます。次に例を示します。

まず、 を使用して関数にブレークポイントを挿入しますbrowser

length.fun=function(x)
{
  lengths=numeric()
  depth=numeric()
  if (x[2]==1)
  {browser("1")
    lengths=x[1]
    depth=x[3]
  }
  browser("2")
  return(cbind(depth,lengths))
}

を使用して関数を呼び出しますtrace

trace(length.fun(m1))

プロンプトが表示され、変数の状態を調べることができます。

> trace(length.fun(m1))
Called from: length.fun(m1)
Browse[1]> browserText()
[1] "2"
Browse[1]> lengths
numeric(0)
Browse[1]> Q

ご覧のとおり、到達した最初のブレークポイントは 2 番目のブレークポイントです。したがって、ifコンストラクトの状態は でFALSEあり、内部のコードは実行されませんでした。これは の値によっても確認されますlengths

于 2013-04-24T14:05:29.170 に答える
2

編集:データがマトリックス形式かデータフレーム形式かは質問から明らかではありません。

If it is a dataframe, then x[2] is a vector with length > 1. したがって、条件は最初の要素のみをテストします。行列の場合は @Roland の説明を参照してください。

初心者として、関数を書くときは「裏返し」から始めることをお勧めします。つまり、最初に関数を記述しないでください。簡単なコードから始めます。与えるものを見てくださいm1[2]。によって与えられるブール値をm1[2]==1確認します (式が TRUE であるか FALSE であるか)。次に、条件を実行してみます。コードのメイン/キー部分が期待どおりに機能し、特定のデータが手元にある場合にのみ、関数をそのコードにラップします。

for達成しようとしている特定の関数は、列 2 のすべての値を循環する必要があります。したがって、または など、ある種のループが必要ですapply

于 2013-04-24T14:05:57.870 に答える
1

split 関数を使用して、データ フレームを個別のデータ フレームのリストに分割できます。データ フレームの名前が foo の場合:

foo.split<-split(foo[,c('length','depth')],foo$number)

このリストがあれば、リストの各要素に名前を付けたり、要素を抽出したりできます。

これはデータフレームに対してのみ機能することに注意してください。マトリックスがある場合は、data.frame() 関数を使用してデータ フレームに変換できます。

于 2013-04-24T14:11:21.427 に答える