web-dev-qa-db-ja.com

R特定のデータフレーム列のApply()関数

データフレームで適用関数を使用したいのですが、最後の5列にのみ関数を適用します。

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y, 2, A)})

これは、yのすべての列にAを適用します

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y[4:9], 2, A)})

これは、Aをyの4〜9列にのみ適用しますが、Bのトータルリターンは、最初の3列から削除されます。それらが必要です。Aを適用したくないだけです。

wifi[,1:3]+B 

また、私が期待した/望んでいたことをしません。

64
skmathur

サンプルのdata.frameとサンプルの関数を使用する(すべての値に+1するだけ)

A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))
wifi

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  1  1  1  1  1  1
#2  2  2  2  2  2  2  2  2  2
#3  3  3  3  3  3  3  3  3  3
#4  4  4  4  4  4  4  4  4  4

data.frame(wifi[1:3], apply(wifi[4:9],2, A) )
#or
cbind(wifi[1:3], apply(wifi[4:9],2, A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

あるいは:

data.frame(wifi[1:3], lapply(wifi[4:9], A) )
#or
cbind(wifi[1:3], lapply(wifi[4:9], A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5
51
thelatemail

ここでlapplyはおそらくapplyよりも良い選択です。最初に適用するとdata.frameが配列に強制されるため、すべての列が同じ型でなければなりません。コンテキストによっては、意図しない結果になる可能性があります。

パターンは次のとおりです。

df[cols] <- lapply(df[cols], FUN)

'cols'ベクトルは、変数名またはインデックスにすることができます。可能な限り名前を使用することを好みます(列の並べ替えに対して堅牢です)。あなたの場合、これは次のようになります:

wifi[4:9] <- lapply(wifi[4:9], A)

列名の使用例:

wifi <- data.frame(A=1:4, B=runif(4), C=5:9)
wifi[c("B", "C")] <- lapply(wifi[c("B", "C")], function(x) -1 * x)
69
leif

前述のように、標準のR apply関数を列(MARGIN=2)に適用するだけです。

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A)

または、略して:

wifi[,4:9] <- apply(wifi[,4:9], 2, A)

これは、A()関数を使用して、列4:9をインプレースで更新します。ここで、na.rmA()の引数であると仮定しましょう。 na.rm=Tを渡して、次のように計算からNA値を削除できます。

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A, na.rm=T)

カスタム関数に渡したい他の引数についても同様です。

1
Adam Erickson

mapply。 すべての列に関数を適用してから、不要な列をドロップするだけだと思います。ただし、異なる列に異なる関数を適用する場合は、dplyrパッケージの mutate が望ましいと思われます。

0
Mox