【问题标题】:How to weigh values based on a variable in R?如何根据 R 中的变量对值进行加权?
【发布时间】:2021-10-04 22:30:21
【问题描述】:

所以我有这样的数据

df <- structure(list(USER = c(1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5), 
    timestamp = structure(c(1614179957.06, 1614181158, 1614181757, 
    1614181938, 1614185926, 1614185987, 1614196768.466, 1614205951.597, 
    1614206076, 1614210969.716, 1614210971.501, 1614210977.449
    ), class = c("POSIXct", "POSIXt"), tzone = "UTC"), source = c("A", 
    "B", "A", "B", "B", "V", "C", "A", "A", "B", "H", "A"), event = c(NA, 
    NA, NA, "y", NA, "y", "y", NA, "y", NA, NA,"y")), row.names = c(NA, 
-12L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x000001f74a701ef0>, sorted = c("USER", 
"timestamp"))

看起来像这样……

USER    timestamp   source  event
1   2/24/21 15:19   A   
1   2/24/21 15:39   B   
1   2/24/21 15:49   A   
1   2/24/21 15:52   B       y
2   2/24/21 16:58   B   
2   2/24/21 16:59   V       y
3   2/24/21 19:59   C       y
4   2/24/21 22:32   A   
4   2/24/21 22:34   A       y
5   2/24/21 23:56   B   
5   2/24/21 23:57   H       
5   2/24/21 23:58   A       y

我基本上是在尝试为每个来源分配权重。因此,我想使用 dplyr 创建一个新列,该列根据距事件 (y) 的距离对行进行加权

所以我特别想看到这两种方式:

  1. 行越靠近事件行,它的价值就越高,实际上是时间衰减。其中event = y 的行是最接近事件发生的行。

所以对于USER =1,你看.....

USER    timestamp   source  event  weight
1   2/24/21 15:19   A              .1
1   2/24/21 15:39   B              .2
1   2/24/21 15:49   A              .3
1   2/24/21 15:52   B       y      .4
  1. 第一个和最后一个事件的重量最大,其他的重量都较轻(U 形)

所以对于USER =1,你看.....

USER    timestamp   source  event  weight
1   2/24/21 15:19   A              .4
1   2/24/21 15:39   B              .1
1   2/24/21 15:49   A              .1
1   2/24/21 15:52   B       y      .4

【问题讨论】:

  • 你要df %&gt;% arrange(USER, event %in% 'y') %&gt;% group_by(USER) %&gt;% mutate(weight = row_number()/10)
  • 抱歉@akrun,已更新
  • 不完全是,我们需要按时间戳排序。通常USER的最终时间戳是event =y,但是如果有另一个USER条目但event = y已经过去的情况,那么权重应该是NA
  • 如果您需要按时间戳订购,只需在排列中添加即可,即df %&gt;% arrange(USER, timestamp, event %in% 'y') %&gt;% group_by(USER) %&gt;% mutate(weight = row_number()/10)
  • 看起来可行!!!放弃投票的答案

标签: r dplyr tidyverse


【解决方案1】:

下面的代码使用这两个条件创建权重列。
第二种方式它使用了一个辅助函数f,以使代码更具可读性。

library(dplyr)

f <- function(n){
  if(n > 1L){
    m <- c(n, rep(1L, n - 2L), n)
    m/sum(m)
  } else 1L
}
df %>%
  group_by(USER) %>%
  mutate(weight1 = seq_along(event)/sum(seq_along(event)),
         weight2 = f(n()))
## A tibble: 12 x 6
## Groups:   USER [5]
#    USER timestamp           source event weight1 weight2
#   <dbl> <dttm>              <chr>  <chr>   <dbl>   <dbl>
# 1     1 2021-02-24 15:19:17 A      NA      0.1     0.4  
# 2     1 2021-02-24 15:39:18 B      NA      0.2     0.1  
# 3     1 2021-02-24 15:49:17 A      NA      0.3     0.1  
# 4     1 2021-02-24 15:52:18 B      y       0.4     0.4  
# 5     2 2021-02-24 16:58:46 B      NA      0.333   0.5  
# 6     2 2021-02-24 16:59:47 V      y       0.667   0.5  
# 7     3 2021-02-24 19:59:28 C      y       1       1    
# 8     4 2021-02-24 22:32:31 A      NA      0.333   0.5  
# 9     4 2021-02-24 22:34:36 A      y       0.667   0.5  
#10     5 2021-02-24 23:56:09 B      NA      0.167   0.429
#11     5 2021-02-24 23:56:11 H      NA      0.333   0.143
#12     5 2021-02-24 23:56:17 A      y       0.5     0.429

【讨论】:

    【解决方案2】:

    我们也可以使用arrange按时间戳排列行,然后通过将row_number()除以10和case_when中的逻辑条件来创建列

    library(dplyr)
    df %>% 
        arrange(USER, timestamp, event %in% 'y') %>%
        group_by(USER) %>% 
        mutate(weight = case_when(row_number() <= match('y', event) ~ row_number()/10))
    

    【讨论】:

    • 这很好,但第二种情况呢?
    • @JohnThomas 抱歉,对于第二种情况,您可以使用df %&gt;% arrange(USER, timestamp, event %in% 'y') %&gt;% group_by(USER) %&gt;% mutate(weight = case_when(row_number() &lt;= match('y', event) ~ row_number()/10), weight = case_when(row_number() %in% c(1, match('y', event)) ~ row_number()[match('y', event)]/10, row_number() &lt;= match('y', event) &amp; row_number() != 1 ~ 0.1))
    猜你喜欢
    • 2022-01-12
    • 2020-05-24
    • 2014-02-15
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2016-03-09
    • 2013-05-13
    相关资源
    最近更新 更多