【问题标题】:Calculate the sum of responses within the past year for each ID计算每个 ID 在过去一年内的响应总和
【发布时间】:2021-10-12 11:27:55
【问题描述】:

我的数据如下所示:

 job    id     date         response
 ny45   088    2021-11-19   1         
 ny21   088    2021-10-12   0
 ny22   088    2021-10-12   0
 ny23   017    2020-09-16   0
 ny23   014    2020-09-16   1
 ny90   017    2020-07-15   1 
 ny67   017    2020-06-02   1

我想计算两件事:

(1) 每个id在过去一年中每个id 的出现次数。如果相同的id 具有相同的date,我希望它在过去出现 0 次时计数(因为它出现在同一天)。像这样的:

 job    id     date         response  occurrences
 ny45   088    2021-11-19   1         2
 ny21   088    2021-10-12   0         0     
 ny22   088    2021-10-12   0         0
 ny23   017    2020-09-16   0         2
 ny23   014    2020-09-16   1         0
 ny90   017    2020-07-15   1         1
 ny67   017    2020-06-02   1         0

(2) 过去一年内的回复数 (response == 1)。同样,如果相同的id 具有相同的date,那么在这种情况下,我希望将其计为 0。我还想只计算以前的响应(即不计算当前日期)。像这样:

 job    id     date         response  occurrences  response_count
 ny45   088    2021-11-19   1         2            0    
 ny21   088    2021-10-12   0         0            0
 ny22   088    2021-10-12   0         0            0
 ny23   017    2020-09-16   0         2            2
 ny23   014    2020-09-16   1         0            0
 ny90   017    2020-07-15   1         1            1
 ny67   017    2020-06-02   1         0            0

任何帮助将不胜感激!谢谢。

【问题讨论】:

  • 您的输入数据与您的预期输出不匹配。
  • 很好发现 - 谢谢 - 我已经纠正了这个问题

标签: r


【解决方案1】:

这是执行此操作的一种方法 -

library(tidyverse)
library(lubridate)

df %>%
  mutate(date = as.Date(date)) %>%
  group_by(id) %>%
  mutate(data = map(date, ~list(
          occurrences = sum(between(date, .x - years(1), .x - 1)), 
          response_count = sum(response[between(date, .x - years(1),.x - 1)])))) %>%
  ungroup %>%
  unnest_wider(data)
         

#   job     id date       response occurrences response_count
#  <chr> <int> <date>        <int>       <int>          <int>
#1 ny45     88 2021-11-19        1           2              0
#2 ny21     88 2021-10-12        0           0              0
#3 ny22     88 2021-10-12        0           0              0
#4 ny23     17 2020-09-16        0           2              2
#5 ny23     14 2020-09-16        1           0              0
#6 ny90     17 2020-07-15        1           1              1
#7 ny67     17 2020-06-02        1           0              0

数据*

df <- structure(list(job = c("ny45", "ny21", "ny22", "ny23", "ny23", 
"ny90", "ny67"), id = c(88L, 88L, 88L, 17L, 14L, 17L, 17L),date = c("2021-11-19",
"2021-10-12", "2021-10-12", "2020-09-16", "2020-09-16", "2020-07-15", 
"2020-06-02"), response = c(1L, 0L, 0L, 0L, 1L, 1L, 1L)), 
class = "data.frame", row.names = c(NA, -7L))

【讨论】:

  • 非常感谢!您能解释一下语法吗?.x - years(1) 表示在过去一年中取行,对吗?那么.x - 1 在做什么呢?
  • .x 是当前日期。 .x - 1 比当前日期少 1 天,因为您想从计算中排除当前日期。
  • 谢谢。我在使用unnest_wider 时遇到问题,它告诉我没有这样的功能。我已经加载了tidyverse,并且我已经重置了 R 会话,但它仍然是一个问题。你知道为什么吗?
  • 你的packageVersion('tidyr') 是什么?我在 1.1.3。您可能需要更新软件包。
  • 尝试使用mutate(char_count = map_dbl(date, ~sum(str_detect(job[between(date, .x - years(1), .x - 1)], 'ny2')))
【解决方案2】:

另一种解决方案

library(lubridate)
df$date=as_datetime(df$date)

cbind(
  df,
  t(
    sapply(1:nrow(df),function(i){
      tmp1=time_length(difftime(df$date[i],df$date),"years")
      tmp2=df$id==df$id[i] & tmp1>0 & tmp1<1
      data.frame(
        "occurences"=sum(tmp2),
        "response_count"=sum(df$response[tmp2])
      )
    })
  )
)

   job id       date response occurences response_count
1 ny45 88 2021-11-19        1          2              0
2 ny21 88 2021-10-12        0          0              0
3 ny22 88 2021-10-12        0          0              0
4 ny23 17 2020-09-16        0          2              2
5 ny23 14 2020-09-16        1          0              0
6 ny90 17 2020-07-15        1          1              1
7 ny67 17 2020-06-02        1          0              0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2021-09-30
    • 2013-07-02
    • 1970-01-01
    • 2021-07-31
    • 2019-02-17
    相关资源
    最近更新 更多