计算以前的事件
Counting previous incidents
这里是第一次提问:
我有代表事件的日期和人物的数据。我想找到一种方法来计算一个人以前参与的次数。所以我想要这样的数据:
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4),
# how many previous times has this id been seen?
count_before = c(0, 0, 0, 0, 1, 0, 2, 1, 1, 1))
df
date person_id count_before
1 2018-01-01 1. 0.
2 2018-01-02 2. 0.
3 2018-01-03 3. 0.
4 2018-01-04 4. 0.
5 2018-01-05 3. 1.
6 2018-01-06 5. 0.
7 2018-01-07 2. 1.
8 2018-01-08 2. 2.
9 2018-01-09 1. 1.
10 2018-01-10 4. 1.
我没有在 R 中按行工作的经验(sapply 可能是答案?)但是使用 dplyr summarize 思考这个问题并且 group_by 到目前为止都失败了。
编辑:修复了预期输出中的不一致。
试试这个,提供我认为你想要的作为你的预期计数。
使用dplyr
:
library(lubridate)
library(dplyr)
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4))
df %>%
arrange(date) %>%
group_by(id) %>%
mutate(count_before = row_number() - 1L) %>%
ungroup()
# # A tibble: 10 × 3
# date id count_before
# <date> <dbl> <int>
# 1 2018-01-01 1 0
# 2 2018-01-02 2 0
# 3 2018-01-03 3 0
# 4 2018-01-04 4 0
# 5 2018-01-05 3 1
# 6 2018-01-06 5 0
# 7 2018-01-07 2 1
# 8 2018-01-08 2 2
# 9 2018-01-09 1 1
# 10 2018-01-10 4 1
基数 R:
do.call(rbind, by(df, df$id, function(a) { a$count <- seq.int(nrow(a))-1L; a;}))
# date id count
# 1.1 2018-01-01 1 0
# 1.9 2018-01-09 1 1
# 2.2 2018-01-02 2 0
# 2.7 2018-01-07 2 1
# 2.8 2018-01-08 2 2
# 3.3 2018-01-03 3 0
# 3.5 2018-01-05 3 1
# 4.4 2018-01-04 4 0
# 4.10 2018-01-10 4 1
# 5 2018-01-06 5 0
这是另一个 base R
解决方案。正如@r2evans 所提到的,还认为您的预期输出有错字。
transform(df, count_new = ave(person_id, person_id, FUN = function(x) cumsum(x == x) - 1))
# date person_id count_before count_new
#1 2018-01-01 1 0 0
#2 2018-01-02 2 0 0
#3 2018-01-03 3 0 0
#4 2018-01-04 4 0 0
#5 2018-01-05 3 1 1
#6 2018-01-06 5 0 0
#7 2018-01-07 2 2 1
#8 2018-01-08 2 1 2
#9 2018-01-09 1 1 1
#10 2018-01-10 4 1 1
使用 data.table
的解决方案。
library(tidyverse)
library(data.table)
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4))
setDT(df)
df[, count_before := seq_len(.N) - 1, by = id]
df
# date id count_before
# 1: 2018-01-01 1 0
# 2: 2018-01-02 2 0
# 3: 2018-01-03 3 0
# 4: 2018-01-04 4 0
# 5: 2018-01-05 3 1
# 6: 2018-01-06 5 0
# 7: 2018-01-07 2 1
# 8: 2018-01-08 2 2
# 9: 2018-01-09 1 1
# 10: 2018-01-10 4 1
我们还可以进行以下操作。
df[, count_before := rowid(id) - 1]
df
# date id count_before
# 1: 2018-01-01 1 0
# 2: 2018-01-02 2 0
# 3: 2018-01-03 3 0
# 4: 2018-01-04 4 0
# 5: 2018-01-05 3 1
# 6: 2018-01-06 5 0
# 7: 2018-01-07 2 1
# 8: 2018-01-08 2 2
# 9: 2018-01-09 1 1
# 10: 2018-01-10 4 1
这里是第一次提问:
我有代表事件的日期和人物的数据。我想找到一种方法来计算一个人以前参与的次数。所以我想要这样的数据:
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4),
# how many previous times has this id been seen?
count_before = c(0, 0, 0, 0, 1, 0, 2, 1, 1, 1))
df
date person_id count_before
1 2018-01-01 1. 0.
2 2018-01-02 2. 0.
3 2018-01-03 3. 0.
4 2018-01-04 4. 0.
5 2018-01-05 3. 1.
6 2018-01-06 5. 0.
7 2018-01-07 2. 1.
8 2018-01-08 2. 2.
9 2018-01-09 1. 1.
10 2018-01-10 4. 1.
我没有在 R 中按行工作的经验(sapply 可能是答案?)但是使用 dplyr summarize 思考这个问题并且 group_by 到目前为止都失败了。
编辑:修复了预期输出中的不一致。
试试这个,提供我认为你想要的作为你的预期计数。
使用dplyr
:
library(lubridate)
library(dplyr)
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4))
df %>%
arrange(date) %>%
group_by(id) %>%
mutate(count_before = row_number() - 1L) %>%
ungroup()
# # A tibble: 10 × 3
# date id count_before
# <date> <dbl> <int>
# 1 2018-01-01 1 0
# 2 2018-01-02 2 0
# 3 2018-01-03 3 0
# 4 2018-01-04 4 0
# 5 2018-01-05 3 1
# 6 2018-01-06 5 0
# 7 2018-01-07 2 1
# 8 2018-01-08 2 2
# 9 2018-01-09 1 1
# 10 2018-01-10 4 1
基数 R:
do.call(rbind, by(df, df$id, function(a) { a$count <- seq.int(nrow(a))-1L; a;}))
# date id count
# 1.1 2018-01-01 1 0
# 1.9 2018-01-09 1 1
# 2.2 2018-01-02 2 0
# 2.7 2018-01-07 2 1
# 2.8 2018-01-08 2 2
# 3.3 2018-01-03 3 0
# 3.5 2018-01-05 3 1
# 4.4 2018-01-04 4 0
# 4.10 2018-01-10 4 1
# 5 2018-01-06 5 0
这是另一个 base R
解决方案。正如@r2evans 所提到的,还认为您的预期输出有错字。
transform(df, count_new = ave(person_id, person_id, FUN = function(x) cumsum(x == x) - 1))
# date person_id count_before count_new
#1 2018-01-01 1 0 0
#2 2018-01-02 2 0 0
#3 2018-01-03 3 0 0
#4 2018-01-04 4 0 0
#5 2018-01-05 3 1 1
#6 2018-01-06 5 0 0
#7 2018-01-07 2 2 1
#8 2018-01-08 2 1 2
#9 2018-01-09 1 1 1
#10 2018-01-10 4 1 1
使用 data.table
的解决方案。
library(tidyverse)
library(data.table)
df <- data.frame(date = seq(ymd('2018-01-01'),ymd('2018-01-10'), by = '1 day'),
id = c(1, 2, 3, 4, 3, 5, 2, 2, 1, 4))
setDT(df)
df[, count_before := seq_len(.N) - 1, by = id]
df
# date id count_before
# 1: 2018-01-01 1 0
# 2: 2018-01-02 2 0
# 3: 2018-01-03 3 0
# 4: 2018-01-04 4 0
# 5: 2018-01-05 3 1
# 6: 2018-01-06 5 0
# 7: 2018-01-07 2 1
# 8: 2018-01-08 2 2
# 9: 2018-01-09 1 1
# 10: 2018-01-10 4 1
我们还可以进行以下操作。
df[, count_before := rowid(id) - 1]
df
# date id count_before
# 1: 2018-01-01 1 0
# 2: 2018-01-02 2 0
# 3: 2018-01-03 3 0
# 4: 2018-01-04 4 0
# 5: 2018-01-05 3 1
# 6: 2018-01-06 5 0
# 7: 2018-01-07 2 1
# 8: 2018-01-08 2 2
# 9: 2018-01-09 1 1
# 10: 2018-01-10 4 1