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