3

次のようなダミーのデータフレームがあるとします。

Data1<-rnorm(20, mean=20)
Data2<-rnorm(20, mean=21)
Data3<-rnorm(20, mean=22)
Data4<-rnorm(20, mean=19)
Data5<-rnorm(20, mean=20)
Data6<-rnorm(20, mean=23)
Data7<-rnorm(20, mean=21)
Data8<-rnorm(20, mean=25)
Index<-rnorm(20,mean=5)

DF<-data.frame(Data1,Data2,Data3,Data4,Data5,Data6,Data7,Data8,Index)

私がやりたいのは、インデックス列に基づいて行ごとに特定の列を削除(NAにする)することです。私は長い道のりを歩み、私がやろうとしていることのアイデアをあなたに与えるためにこれをしました:

DF[DF$Index>5.0,8]<-NA
DF[DF$Index>=4.5 & DF$Index<=5.0,7:8]<-NA
DF[DF$Index>=4.0 & DF$Index<=4.5,6:8]<-NA
DF[DF$Index>=3.5 & DF$Index<=4.0,5:8]<-NA
DF[DF$Index>=3.0 & DF$Index<=3.5,4:8]<-NA
DF[DF$Index>=2.5 & DF$Index<=3.0,3:8]<-NA
DF[DF$Index>=2.0 & DF$Index<=2.5,2:8]<-NA
DF[DF$Index<=2.0,1:8]<-NA

これはそのままでは問題なく動作しますが、あまり適応性がありません。列の数が変更された場合、または条件ステートメントを微調整する必要がある場合は、コード全体を書き直すのは面倒です(実際のデータセットははるかに大きくなります)。

私がやりたいのは、いくつかの変数を定義してから、ある種のループを実行するか、上記のコード行が実行することを正確に実行するために適用できることです。

例として、私の長いコードを複製するために、この種のロジックの線に沿った何か:

NumCol<-8
Max<-5
Min<-2.0

if index > Max, then drop NumCol
if index >= (Max-0.5) & <=Max, than drop NumCol:(NumCol -1)

repeat until reach Min

それがRで最も論理的な推論の行であるかどうかはわかりません。また、ループと適用がかなり苦手なので、上記の長いコード行を複製して、上記の変数を調整します。

4

2 に答える 2

4

data.frameをマトリックスに変更してもかまわない場合は、マトリックスによるインデックス作成を使用するソリューションを次に示します。ドロップするインデックスの2列のマトリックスの構築は、apply関数ファミリーの優れたレビューです。

Seq      <- seq(Min, Max, by = 0.5)
col.idx  <- lapply(findInterval(DF$Index, Seq) + 1, seq, to = NumCol)
row.idx  <- mapply(rep, seq_along(col.idx), sapply(col.idx, length))
drop.idx <- as.matrix(data.frame(unlist(row.idx), unlist(col.idx)))

M <- as.matrix(DF)
M[drop.idx] <- NA
于 2012-11-09T02:08:31.970 に答える
1

これがメモリ効率の良い(しかし私はエレガントとは言えない)data.tableソリューションです

非常に便利な関数を使用して、findIntervalループよりも小さい/大きいを変更します

# 
library(data.table)
DT <- data.table(DF)
# create an index column which 1:8 represent your greater than less than
DT[,IND := findInterval(Index, c(-Inf, seq(2,5,by =0.5 ), Inf))]

# the columns you want to change
changing <- names(DT)[1:8]


setkey(DT, IND)
# loop through the indexes and alter by reference
for(.ind in DT[,unique(IND)]){
   # the columns you want to change
   .which <- tail(changing, .ind)
   # create a call to `:=`(a = as(NA, class(a), b= as(NA, class(b))
   pairlist <- mapply(sprintf, .which, .which, MoreArgs = list(fmt =  '%s = as(NA,class(%s))'))
   char_exp <- sprintf('`:=`( %s )',paste(pairlist, collapse = ','))  
 .e <- parse(text = char_exp)
  DT[J(.ind), eval(.e)]

}
于 2012-11-09T02:14:27.577 に答える