2011-11-08 10 views
1

データフレームの各行に以下のように関数を適用したいと思います。私は、データフレームに数字だけが含まれている場合にapplyを使う方法を知っていますが、行にブール値/論理、文字列、整数が含まれているとどうなりますか?例:この機能を各行にデータフレームに適用すると良いでしょうか?

df <- data.frame(x=1:10, 
       y=c(TRUE, FALSE), 
       z=letters[1:10], 
       stringsAsFactors=FALSE) 

RowFunction <- function(row) { 
    if (row$y) return(row$x) 
    return (row$z) 
} 

sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) }) 

これを行うより良い方法はありますか?私の最初の考えは、をRowFunctionの先頭に追加した後にapply(df, 1, RowFunction)を使用することでしたが、applyは異なるデータ型を含む行を処理できない配列に適用するため、これは機能しません。

私の知る限りでは、これを行うクリーナーの方法がsapply(1:dim(df)[1], ...)よりもあるかどうかを知りたいと思います。何か案は?

ありがとうございます!この場合

+1

私はベクトル中_all_の要素があることになることを指摘したいと思います同じモード。モードやタイプが異なる結果を得る唯一の方法は、リストを返すことです。 –

答えて

6

、あなたは、単にifelseを使用することができます利便性と可読性のために

sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) }) 
[1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j" 

with(df, ifelse(y, x, z)) 
[1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j" 

を私はまたwithを使用 - これは、あなたが$演算子を使用せず、名前だけで列を参照することができます。

+1

もし私が 'ifelse'と' with' ...のためにできたら+2私のお気に入りの2人! –

0

ifelse機能がlapplyでそれを行うことができます。

lapply(df$y, ifelse, df$x, df$z) # does return list with varying modes 

私の以前の(より不格好)バージョン:

res <- list() 
for(i in seq_along(rownames(df))) { res <- c(res, df[i,1+2*!df[i,"y"] ]) } 
res 
#-------- 
[[1]] 
[1] 1 

[[2]] 
[1] "b" 

[[3]] 
[1] 3 

[[4]] 
[1] "d" 

[[5]] 
[1] 5 

[[6]] 
[1] "f" 

[[7]] 
[1] 7 

[[8]] 
[1] "h" 

[[9]] 
[1] 9 

[[10]] 
[1] "j"