【问题标题】:Speed up loop for assigning ratings based on different conditions根据不同条件分配评级的加速循环
【发布时间】:2012-06-21 13:37:36
【问题描述】:

我希望加快循环,根据不同的条件为行分配评级。根据不同的条件分配六个不同的等级(0 到 5)。我尝试使用带有每个条件的 if 语句的 for 循环来执行此操作,但是要经过数百万行,这确实是没有选择的。我什至不知道花了多长时间才完成。在我手动停止它之前它已经运行了几个小时。

规则是:

Rating 0: if df$Bounce >= 75 and df$time<10 and df$view<1
Rating 1: if df$Bounce >= 75 or df$Assist<1
Rating 2: if df$Bounce < 75 and df$Assist<2
Rating 3: if df$Bounce < 75 and df$Assist<3
Rating 4: if df$Bounce < 75 and df$Assist<=4
Rating 5: if df$Bounce < 75 and df$Assist>=5

我的脚本中有更多这些“慢”语句,所以这个问题的答案将加快很多进程!

一个小的示例数据集

tc <- textConnection('
belongID   uniqID   Bounce     Assist   time   view    
   1           101     90       10       7       0      
   1           102     75        0       8      10
   2           103     10       30       4       2
   2           104     50        3       1      10
   2           105     74        2       5       4
   3           106      5        1       2       8  ')

df <- read.table(tc,header=TRUE)

结果应该产生相同的数据集,其中包含一个新列 Rating 和根据规则的评级:

belongID   uniqID   Bounce     Assist   time   view     Rating    
   1           101     90       10       7       0       0
   1           102     75        0       8      10       1
   2           103     10       30       4       2       5
   2           104     50        3       1      10       4
   2           105     74        2       5       4       3
   3           106      5        1       2       8       2

编辑:更改等级 1 条件!

【问题讨论】:

  • 您是否为每种情况实现了单独的if 语句,例如if (df$Bounce &gt;= 75 &amp;&amp; df$time &lt; 10 &amp;&amp; df$view &lt; 1) df$rating = 0; else if ... 或者你做了类似决策树的东西:if (df$Bounce &gt;= 75) { if (df$time &lt; 10 &amp;&amp; df$view &lt; 1) df$rating = 0; else if (df$Assist &lt; 1) df$rating = 1; } else { ... }
  • 我是第一个! - 还编辑了评分 1 条件

标签: performance r loops


【解决方案1】:

这是一个函数中的简单算法,可以满足您的要求。由于这仅包含三个规则,因此应该非常快。 (不过,我隐含假设Assist 始终是整数。)

rating <- function(Bounce, Assist, time, view){
  x <- pmin(5, Assist + 1)
  x[Bounce >= 75 & time<10 & view<1] <- 0
  x[Bounce >= 75 & Assist < 1] <- 1
  x
}

within(df, rating <- rating(Bounce, Assist, time, view))

  belongID uniqID Bounce Assist time view rating
1        1    101     90     10    7    0      0
2        1    102     75      0    8   10      1
3        2    103     10     30    4    2      5
4        2    104     50      3    1   10      4
5        2    105     74      2    5    4      3
6        3    106      5      1    2    8      2

【讨论】:

  • 我真的很喜欢这个解决方案,但我确实有一个问题。对于等级 4 的条件是:等级 4: if df$Bounce = 75 |辅助
  • 不能只用x &lt;- pmin(5, Assist)x[Bounce &gt;= 75 | Assist &lt; 1] &lt;- 1 使其与编辑的等级1 条件和等级4 条件的错误处理兼容吗?我不知道+1 最初的用途是什么?
  • 辅助值也可以是浮点数。还有像pmin这样的方法吗?
  • @MaxvanderHeijden Assist + 1 只是反映了&lt; 条件,从而使您的评分和辅助失步了1。pmin() 适用于浮点值。我关于整数值的观点很明显,如果Assist 的值(例如)3.5,我的简化算法将不起作用。
【解决方案2】:

不要使用循环:

df$rating <- 999

df[df$Bounce >= 75 & df$time < 10 & df$view<1, "rating"] <- 0
df[df$Bounce >= 75 & df$Assist < 1 & df$rating == 999, "rating"] <- 1
df[df$Bounce < 75 & df$Assist < 2 & df$rating == 999, "rating"] <- 2
df[df$Bounce < 75 & df$Assist < 3  & df$rating == 999, "rating"] <- 3
df[df$Bounce < 75 & df$Assist <= 4  & df$rating == 999, "rating"] <- 4
df[df$Bounce < 75 & df$Assist >= 5 & df$rating == 999, "rating"] <- 5

rating == 999 检查是必需的,因为您的规则不是互斥的。如果它们应该是,那么您的逻辑就有错误。否则,这将确保没有规则覆盖之前的规则。

【讨论】:

    【解决方案3】:

    试试

    dumfun<-function(w,x,y,z){
    if(w>=75&&x<10&&y<1){return(0)}
    if(w>=75&&z<1){return(1)}
    if(w<75&&z<2){return(2)}
    if(w<75&&z<3){return(3)}
    if(w<75&&z<5){return(4)}
    if(w<75&&z>5){return(5)}
    }
    
    df$Rating<-mapply(dumfun,df$Bounce,df$time,df$view,df$Assist)
    

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 1970-01-01
      • 2010-11-17
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多