使用函数添加另一个条件

时间:2012-10-05 17:13:02

标签: r

如果标题可能不清楚,我道歉。

使用

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)
  }
)

在此示例中,新df将为:

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)这样的东西,但我想不出一个好的方法将上述条件添加到函数中。我希望我对我的问题很清楚。谢谢!

3 个答案:

答案 0 :(得分: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)
}

x是您的data.frame,ref是引用变量(profit),add是一个逻辑,表明您是否希望bid为向量(如果add=FALSE)或您的原始data.frame以bid作为新列(如果add=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

答案 1 :(得分:2)

最直接的方法是使用transform()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

答案 2 :(得分: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