1

タイトルが分かりにくいかもしれませんがご容赦ください。

df <- data.frame(profit = c(1, 1, 0, 0, 0, -1),
                 offerA = round(rnorm(6), 2), 
                 offerB = round(runif(6), 2), 
                 offerC = sample(1:6))

df
  profit offerA offerB offerC
1      1  -0.51   0.91      6
2      1  -0.03   0.75      4
3      0  -1.02   0.28      5
4      0   0.63   0.61      1
5      0   2.32   0.37      2
6     -1  -0.15   0.43      3

次の条件の下でbid、値に応じて名前が付けられたフィールドを追加する必要があります。profit

with(df,
  if (profit > 0) {
    apply(cbind(offerA, offerB, offerC), 1, max)
  }
  else if (profit = 0) {
    apply(cbind(offerA, offerB, offerC), 1, mean)
  }
  else if (profit < 0) {
    apply(cbind(offerA, offerB, offerC), 1, min)
  }
)

この例では、 newdfは次のようになります。

df
  profit offerA offerB offerC   bid
1      1  -0.51   0.91      6     6
2      1  -0.03   0.75      4     4
3      0  -1.02   0.28      5  1.42
4      0   0.63   0.61      1  0.75
5      0   2.32   0.37      2  1.56
6     -1  -0.15   0.43      3 -0.15

の値は行ごとに計算されるため、次のような関数を使用できるようにbid関数を書きたいのですが、上記の条件を関数に追加する良い方法が思いつきません。私の質問が明確であることを願っています。ありがとう!addBid()apply(df, 1, addBid)

4

3 に答える 3

3

多分これは役に立つかもしれません

bid <- function(x, ref, add=FALSE){
  ref <- match(ref,names(df))
  result <- ifelse(df[,ref]>0, apply(df[,-ref],1,max), 
         ifelse(df[,ref]==0, rowMeans(df[,-ref]),  apply(df[,-ref],1,min)) )
  if(add){
    result <- cbind(x, bid=result)
  }
  return(result)
}

ここで、はxdata.frameでrefあり、は参照変数(profit)であり、ベクトル(if )として使用するか、新しい列(if)として元のdata.frameを使用するaddかを論理的に示します。bidadd=FALSEbidadd=TRUE

set.seed(001)
df <- data.frame(profit = c(1, 1, 0, 0, 0, -1),
                 offerA = round(rnorm(6), 2), 
                 offerB = round(runif(6), 2), 
                 offerC = sample(1:6))

> bid(df, ref='profit')  # returns a vector
[1]  3.000000  4.000000  1.643333  1.033333  1.016667 -0.820000
> bid(df, ref='profit', add=TRUE) # returns a data.frame = df + bid
  profit offerA offerB offerC       bid
1      1  -0.63   0.69      3  3.000000
2      1   0.18   0.38      4  4.000000
3      0  -0.84   0.77      5  1.643333
4      0   1.60   0.50      1  1.033333
5      0   0.33   0.72      2  1.016667
6     -1  -0.82   0.99      6 -0.820000
于 2012-10-05T17:26:05.520 に答える
2

これを行う最も直接的な方法は、おそらく、別の関数を記述する代わりにtransform()orを使用することです。within()@Jilber のサンプル データ (および同じ変換ロジック) を使用した例を以下に示しtransform()ます。

transform(df, bid = ifelse(profit > 0, apply(df[-1], 1, max), 
                           ifelse(profit == 0, rowMeans(df[-1]), 
                                  apply(df[-1], 1, min))))
#   profit offerA offerB offerC       bid
# 1      1  -0.63   0.69      3  3.000000
# 2      1   0.18   0.38      4  4.000000
# 3      0  -0.84   0.77      5  1.643333
# 4      0   1.60   0.50      1  1.033333
# 5      0   0.33   0.72      2  1.016667
# 6     -1  -0.82   0.99      6 -0.820000
于 2012-10-05T18:02:50.710 に答える
1

おそらくもっとエレガントなものがありますが、これはうまくいくと思います:

foo <- function(x){
    if (x[1] > 0){
        return(max(x[-1]))
    }
    if (x[1] == 0){
        return(mean(x[-1]))
    }
    if (x[1] < 0){
        return(min(x[-1]))
    }
}

df$bid <- apply(df,1,foo)
df
  profit offerA offerB offerC       bid
1      1  -0.17   0.14      2  2.000000
2      1   1.75   0.46      5  5.000000
3      0   0.38   0.90      1  0.760000
4      0   0.34   0.35      4  1.563333
5      0   0.22   0.63      3  1.283333
6     -1  -1.09   0.34      6 -1.090000
于 2012-10-05T17:21:43.303 に答える