【问题标题】:Cross joining for the computation of a new variable交叉连接计算新变量
【发布时间】:2023-03-17 15:15:01
【问题描述】:

我有一个游戏数据集,我观察一个玩家的点数。

da = data.frame(points = c(144,186,220,410,433))

da                
  points
1    144
2    186
3    220
4    410
5    433  

我现在也知道玩家所在的关卡,因为我知道不同关卡的积分范围。

ranges = data.frame(level = c(1,2,3,4,5), points_from = c(0,100,200,300,430), points_to = c(100,170,300,430,550))

ranges
  level points_from points_to
1     1           0       100
2     2         100       170
3     3         200       300
4     4         300       430
5     5         430       550  

现在我想计算一个新变量,它表示玩家离下一个关卡有多远。由该特定级别的 da$points/ranges$points_to 计算得出。

例如,如果玩家有144分,达到170分达到下一个等级,则等级进度为144/170。

因此,我想要的数据集如下所示:

da_new = data.frame(points = c(144,186,220,410,433), points_to = c(170,300,300,430,550), level_progress = c(144/170,186/300,220/300,410/430,433/550))

da_new
  points points_to level_progress
1    144       170         0.8471
2    186       300         0.6200
3    220       300         0.7333
4    410       430         0.9535
5    433       550         0.7873

我现在如何计算这个变量?

【问题讨论】:

  • 你怎么知道186在哪一关?范围从 100-170 到 200-300

标签: r transform tidyr dplyr


【解决方案1】:

主要思想是使用merge(da, ranges, all = T)在数据之间做一个"cross join"。然后,我们过滤到pointspoints_frompoints_to 之间的位置(意味着186 不在最终数据中)。

library(dplyr)
merge(da, ranges, all = T) %>%
    # keep only where points fall between points_from and points_to
    filter(points >= points_from & points <= points_to) %>%
    mutate(level_progress = points / points_to)

  points level points_from points_to level_progress
1    144     2         100       170      0.8470588
2    220     3         200       300      0.7333333
3    410     4         300       430      0.9534884
4    433     5         430       550      0.7872727

另一种选择是过滤points &lt;= point_to 的位置,并找到points 最接近points_to 的位置(此方法保持 186):

merge(da, ranges, all = T) %>%
    filter(points <= points_to) %>%
    group_by(points) %>%
    slice(which.min(abs(points - points_to))) %>%
    mutate(level_progress = points / points_to)

  points level points_from points_to level_progress
   <dbl> <dbl>       <dbl>     <dbl>          <dbl>
1    144     2         100       170          0.847
2    186     3         200       300          0.62 
3    220     3         200       300          0.733
4    410     4         300       430          0.953
5    433     5         430       550          0.787

【讨论】:

  • 谢谢,我最喜欢 dplyr,所以这是一个非常有用的解决方案!
  • 感谢@Adam,我编辑了我的代码以引入dplyr
【解决方案2】:

这是使用 findInterval 的基本 R 解决方案

da_new <- da
da_new$points_to <- ranges$points_to[findInterval(da_new$points,c(0,ranges$points_to))]
da_new$level_progress <- da_new$points/da_new$points_to

这样

> da_new
  points points_to level_progress
1    144       170      0.8470588
2    186       300      0.6200000
3    220       300      0.7333333
4    410       430      0.9534884
5    433       550      0.7872727

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多