準備: この質問はほとんどが教育的価値があり、アプローチが完全に最適ではない場合でも、目前の実際のタスクは完了しています。私の質問は、以下のコードを速度のために最適化したり、よりエレガントに実装したりできるかどうかです。おそらく、plyr や reshape などの追加のパッケージを使用します。元の行の一部には NA しか含まれておらず、追加のチェックを行う必要があるため、実際のデータで実行すると、シミュレートされたデータよりもはるかに長い約 140 秒かかります。比較すると、シミュレートされたデータは約 30 秒で処理されます。
条件: データセットには 360 個の変数が含まれており、12 個のセットの 30 倍です。名前を V1_1、V1_2... (最初のセット)、V2_1、V2_2 ... (2 番目のセット) などとしましょう。12 個の変数の各セットには、二分法 (はい/いいえ) の応答が含まれており、実際にはキャリア ステータスに対応しています。たとえば、仕事(はい/いいえ)、勉強(はい/いいえ)など、合計12のステータスを30回繰り返します。
タスク: 当面のタスクは、12 の二分変数の各セットを、12 の応答カテゴリ (仕事、勉強など) を持つ単一の変数に再コード化することです。最終的に、それぞれ 12 の応答カテゴリを持つ 30 の変数を取得する必要があります。
データ: 実際のデータセットを投稿することはできませんが、シミュレートされた近似値は次のとおりです。
randomRow <- function() {
# make a row with a single 1 and some NA's
sample(x=c(rep(0,9),1,NA,NA),size=12,replace=F)
}
# create a data frame with 12 variables and 1500 cases
makeDf <- function() {
data <- matrix(NA,ncol=12,nrow=1500)
for (i in 1:1500) {
data[i,] <- randomRow()
}
return(data)
}
mydata <- NULL
# combine 30 of these dataframes horizontally
for (i in 1:30) {
mydata <- cbind(mydata,makeDf())
}
mydata <- as.data.frame(mydata) # example data ready
私の解決策:
# Divide the dataset into a list with 30 dataframes, each with 12 variables
S1 <- lapply(1:30,function(i) {
Z <- rep(1:30,each=12) # define selection vector
mydata[Z==i] # use selection vector to get groups of variables (x12)
})
recodeDf <- function(df) {
result <- as.numeric(apply(df,1,function(x) {
if (any(!is.na(df))) which(x == 1) else NA # return the position of "1" per row
})) # the if/else check is for the real data
return(result)
}
# Combine individual position vectors into a dataframe
final.df <- as.data.frame(do.call(cbind,lapply(S1,recodeDf)))
全体として、2 つの *apply 関数があり、1 つはリスト全体、もう 1 つはデータフレーム行全体です。これにより、少し遅くなります。助言がありますか?前もって感謝します。