根据第二列的值将校正因子应用于一列

时间:2013-06-26 22:40:24

标签: r

示例数据

A<-c(1,4,5,6,2,3,4,5,6,7,8,7)
B<-c(4,6,7,8,2,2,2,3,8,8,7,8)
DF<-data.frame(A,B)

我想要做的是根据B列的值对A列应用校正因子。规则将是这样的

If B less than 4  <- Multiply A by 1
If B equal to  4 and less than 6  <- Multiply A by 2
If B equal or greater than 6 <-  Multiply by 4

我想我可以写一个&#34; if&#34;声明(我很高兴看到一个很好的例子),但我也有兴趣使用方括号索引来加快速度。

最终结果如下所示

A  B
2  4
16 6
20 7
24 8

ECT

3 个答案:

答案 0 :(得分:2)

使用此:

within(DF, A <- ifelse(B>=6, 4, ifelse(B<4, 1, 2)) * A)

或者这个(由@agstudy更正):

within(DF, {A[B>=6] <- A[B>=6]*4; A[B>=4 & B<6] <- A[B>=4 & B<6]*2})

基准:

DF <- data.frame(A=rpois(1e4, 5), B=rpois(1e4, 5))
a <- function(DF) within(DF, A <- ifelse(B>=6, 4, ifelse(B<4, 1, 2)) * A)
b <- function(DF) within(DF, {A[B>=6] <- A[B>=6]*4; A[B>=4 & B<6] <- A[B>=4 & B<6]*2})

identical(a(DF), b(DF))
#[1] TRUE

microbenchmark(a(DF), b(DF), times=1000)
#Unit: milliseconds
#  expr      min        lq   median        uq      max neval
# a(DF) 8.603778 10.253799 11.07999 11.923116 53.91140  1000
# b(DF) 3.763470  3.889065  5.34851  5.480294 39.72503  1000

答案 1 :(得分:1)

与@Ferdinand解决方案类似,但使用transform

transform(DF, newcol = ifelse(B<4,  A,
                                   ifelse(B>=6,4*A,2*A)))
      A B newcol
1  1 4      2
2  4 6     16
3  5 7     20
4  6 8     24
5  2 2      2
6  3 2      3
7  4 2      4
8  5 3      5
9  6 8     24
10 7 8     28
11 8 7     32
12 7 8     28

答案 2 :(得分:1)

我更喜欢使用findInterval作为此类操作的一组因子的索引。具有多个ifelse调用的嵌套测试条件和后续向量的扩散冒犯了我的效率敏感度:

 DF$A <- DF$A * c(1,2,4)[findInterval(DF$B, c(-Inf,4,6,Inf) ) ]
 DF
    A B
1   2 4
2  16 6
3  20 7
4  24 8
snipped ....

基准:

DF <- data.frame(A=rpois(1e4, 5), B=rpois(1e4, 5))
a <- function(DF) within(DF, A <- ifelse(B>=6, 4, ifelse(B<4, 1, 2)) * A)
b <- function(DF) within(DF, {A[B>=6] <- A[B>=6]*4; A[B>=4 & B<6] <- A[B>=4 & B<6]*2})
ccc <- function(DF) within(DF, {A * c(1,2,4)[findInterval(B, c(-Inf,4,6,Inf) ) ]})
microbenchmark(a(DF), b(DF), ccc(DF), times=1000)
#-----------
Unit: microseconds
    expr      min        lq    median        uq      max neval
   a(DF) 7616.107 7843.6320 8105.0340 8322.5620 93549.85  1000
   b(DF) 2638.507 2789.7330 2813.8540 3072.0785 92389.57  1000
 ccc(DF)  604.555  662.5335  676.0645  698.8665 85375.14  1000

注意:如果我编写自己的函数,我不会使用within完成此操作,但是为了公平对待早期的工作,我会把它变成苹果&lt; - &gt;苹果。