第一次问这里:
我有包含日期和代表事件的人员的数据。我想找到一种方法来计算一个人以前参与的次数。所以我想要看起来像这样的数据:
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中逐行工作的经验(也许是答案吗?),但到目前为止,使用dplyr summary和group_by来思考这个问题都失败了。
编辑:修复了预期输出中的不一致之处。
答案 0 :(得分:2)
尝试一下,提供我认为您期望的数量。
使用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
答案 1 :(得分:2)
这是另一个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
答案 2 :(得分:0)
使用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