0

48列の大きなデータフレームがあり、データフレームの各行で関数を実行して、関数によって指定されたテストに合格した列がNAに設定されるようにしたいと考えています。このテストでは、別のデータ フレームから数値を取得します。adply はこれに自然に適合しますが、私が望む結果を得るには問題があります。

説明させてください:

操作したいデータフレームの例を次に示します。

 >df
  pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir
1  1   0.1           NA           NA           NA           NA
2  2   0.2           NA           NA        1.344        324.0
3  3   0.3           NA           NA        0.445        167.0
4  4   0.4        1.455        354.2        0.322        321.2

テストが派生する小さなデータ フレームは次のとおりです。

> tcell
  depth  name
1   0.2 Cell1
2   0.4 Cell2
3   0.6 Cell3
4   0.8 Cell4

全体的な考え方は、大きなデータ フレームにリストされている実際の深さよりも深いセルのデータ ポイントに NA を割り当てることです (つまり、3 行目では、深さは 0.3 ですが、Cell2 に対応する 2 つのデータ ポイントがあります。 0.4 m の深さなので、これらはエラーです (これらを NA にしたい)。

一度に行を受け取る関数を書きたい: 1) 楽器の深さをつかむ 2) 列名のリストを取得する 3) 楽器の深さよりも深いセルのインデックスを取得する 4) 名前を取得するこれらのセル (つまり、Cell1、Cell2、Cell4 など) 5) 正規表現を使用して、列名のリストのどこに対応するセル (つまり、Cell1_avgdir、Cell1_avgvel など) を持つ列を見つけます。 6) これらのインデックスを使用して、それらを設定します。列の値を NA にします。

これが私がこれまでに持っているものです:

depthNA = function(x) {
  depth = x$depth
  nms = names(df)
  ind = as.character(which(depth < tcell$depth))
  c = tcell$name[ind]
  patt = paste(c,collapse="|")
  c_ind = grep(patt,nms)
  x[,c_ind] <- NA
}

adply(df,1,depthNA)

残念ながら、これは私が思っていたようには機能しません。現在、その理由を突き止めようとしています。

それは私にこれを与えます:

  pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir V1
1  1   0.1           NA           NA           NA           NA NA
2  2   0.2           NA           NA        1.344        324.0 NA
3  3   0.3           NA           NA        0.445        167.0 NA
4  4   0.4        1.455        354.2        0.322        321.2 NA

私が欲しいのは:

  pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir
1  1   0.1           NA           NA           NA           NA
2  2   0.2           NA           NA           NA           NA
3  3   0.3           NA           NA           NA           NA
4  4   0.4        1.455        354.2        0.322        321.2

うまくいけば、私は自分の問題を十分に説明しました。1)私が始めたことを修正するか、2)私が知らないより良い方法を教えてください。

-SH

4

1 に答える 1

1

以下は、アイデアの概要に答えるが、出力と一致しない回答です。出力が正しいかどうかについては、上記の私のコメントを参照してください。reshape2答えは、参加を容易にすることに依存しています。

まず、次のようにデータを読み込みます。

df <- read.table(text = "  pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir
1  1   0.1           NA           NA           NA           NA
2  2   0.2           NA           NA        1.344        324.0
3  3   0.3           NA           NA        0.445        167.0
4  4   0.4        1.455        354.2        0.322        321.2", header = TRUE)

tcell <- read.table(text = " depth  name
1   0.2 Cell1
2   0.4 Cell2
3   0.6 Cell3
4   0.8 Cell4", header = TRUE)

次に、問題に対処します。

library(reshape2)

#Melt into long format
df.m <- melt(df, id.vars = 1:2)
#Split the column into two new columns based on _
df.m[, c("Cell", "OtherCol")] <- with(df.m, colsplit(variable, "_", c("Cell", "OtherCol")))
#Merge together with tcell
df.m <- merge(df.m, tcell, by.x = "Cell", by.y = "name")
#Add a new column which sets the offending values to NA
df.m <- transform(df.m, newvalue = ifelse(value > depth.y, NA, value))
#Cast back into wide format
dcast(pt + depth.x ~ variable, value.var = "newvalue", data = df.m)

  pt depth.x Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir
1  1     0.1           NA           NA           NA           NA
2  2     0.2           NA           NA           NA           NA
3  3     0.3           NA           NA           NA           NA
4  4     0.4           NA           NA        0.322           NA
于 2012-06-06T17:45:02.363 に答える