1

既存のデータフレームの列名のループを使用して、古い列の1つに基づいて新しい列を作成しようとしています。サンプルデータは次のとおりです。

 sample<-list(c(10,12,17,7,9,10),c(NA,NA,NA,10,12,13),c(1,1,1,0,0,0))
    sample<-as.data.frame(sample)
    colnames(sample)<-c("x1","x2","D")

>sample
x1  x2  D
10  NA  1
12  NA  1
17  NA  1
7   10  0
9   20  0
10  13  0

ここで、for loopD=1の場合はD=0に関連する値を持ち、D=0の場合はD=1に関連する値を持つ2つの変数x1.impとx2.impを生成しようとしています(ここでは実際には必要ありませんがfor loop、大きな列(変数)を持つ元のデータセットの場合、次の条件に基づいてループが本当に必要です)。

for (i in names(sample[,1:2])){
sample$i.imp<-with (sample, ifelse (D==1, i[D==0],i[D==1]))
i=i+1
return(sample)
}


Error in i + 1 : non-numeric argument to binary operator

ただし、以下は機能しますが、新しい列の名前をimp.x2およびimp.x3として指定しません。

for(i in sample[,1:2]){
impt.i<-with(sample,ifelse(D==1,i[D==0],i[D==1]))
i=i+1
print(as.data.frame(impt.i))
 }

impt.i
1      7
2      9
3     10
4     10
5     12
6     17
  impt.i
1     10
2     12
3     13
4     NA
5     NA
6     NA

私はすでにループのない解決策を知っていることに注意してください[ここ]。ループが欲しいです。

期待される出力:

x1  x2  D   x1.impt x2.imp 
10  NA  1   7       10      
12  NA  1   9       20
17  NA  1   10      13
7   10  0   10      NA
9   20  0   12      NA
10  13  0   17      NA

この点に関して、貴重なご意見をいただければ幸いです。

4

2 に答える 2

3

これはナッツですが、あなたがそれを求めているので...最小限の変更であなたのコードは次のようになります:

for (i in colnames(sample)[1:2]){
  sample[[paste0(i, '.impt')]] <- with(sample, ifelse(D==1, get(i)[D==0],get(i)[D==1]))
}

いくつかのコメント:

  1. names(sample[,1:2])よりエレガントなものに置き換えられましたcolnames(sample)[1:2]
  2. $インタラクティブに使用するためのものです。代わりに、プログラミング時、つまり列名を解釈する場合は、[またはを使用する必要があるため、次のよう[[に置き換えsample$i.impました。sample[[paste0(i, '.impt')]]
  3. 内部withでは、がの場合は表示されi[D==0]ないため、を使用して逆参照する必要があります。x1[D==0]i"x1"get
  4. sampledata.frameはかなり一般的な関数の名前でもあるため、名前を付けないでください。
于 2013-03-16T01:04:30.253 に答える
1

これはうまくいくはずです、

test <- sample[,"D"] == 1
for (.name in names(sample)[1:2]){
  newvar <- paste(.name, "impt", sep=".")
  sample[[newvar]] <- ifelse(test, sample[!test, .name], 
                                   sample[test, .name]) 
}

sample
于 2013-03-16T00:52:21.570 に答える