Представьте, что у меня есть следующий набор данных
Date Group Value
01-01-19 A X
01-01-19 A Y
01-01-19 A Z
02-01-19 A X
02-01-19 A Y
02-01-19 A Z
02-01-19 A W
01-01-19 B X
01-01-19 B Y
01-01-19 B Z
02-01-19 B X
02-01-19 B X
02-01-19 B Z
02-01-19 B V
Итак, есть две группы и две даты. Я хочу видеть по группам и по датам, какие значения являются новыми.
Результирующий фрейм данных должен выглядеть примерно так
group date new_values
A 01-01-19 3
A 02-01-19 1
B 01-01-19 3
B 02-01-19 1
В конце концов я просто подсчитал количество значений на дату в группе и взял разницу. Но при этом не учитываются значения, исчезнувшие с предыдущей даты. Я понятия не имею, как это сделать. Возможно, пакет data.table
может принести релиз
Одна возможность:
library(dplyr)
df %>%
arrange(Date = as.Date(Date, "%d-%m-%y")) %>%
group_by(Group, Value) %>%
mutate(New = row_number()) %>%
group_by(Group, Date) %>%
summarise(New = sum(New == 1))
Выход:
# A tibble: 4 x 3
# Groups: Group [2]
Group Date New
<fct> <fct> <int>
1 A 01-01-19 3
2 A 02-01-19 1
3 B 01-01-19 3
4 B 02-01-19 1
Вышеприведенное предполагает, что ваша дата указана в формате day-month-year
; если это не так, вы просто меняете "%d-%m-%y"
на "%m-%d-%y"
.
Используя dplyr
, мы можем сначала group_by
Group
создать столбец (orig
), который будет TRUE
, если он будет виден впервые в группе. Затем мы group_by
Group
и Date
и подсчитываем количество таких исходных значений.
library(dplyr)
df %>%
group_by(Group) %>%
mutate(orig = !duplicated(Value)) %>%
group_by(Group, Date) %>%
summarise(new_values = sum(orig))
# Group Date new_values
# <fct> <fct> <int>
#1 A 01-01-19 3
#2 A 02-01-19 1
#3 B 01-01-19 3
#4 B 02-01-19 1
Функция rowid подсчитывает появление комбинации столбцов, начиная с 1:
library(data.table)
setDT(DT)
DT[, new := rowid(Group, Value) == 1L]
DT[, .(n_new = sum(new)), by=.(Group, Date)]
# Group Date n_new
# 1: A 01-01-19 3
# 2: A 02-01-19 1
# 3: B 01-01-19 3
# 4: B 02-01-19 1
library(data.table)
dt <- data.table(read.table(text = "
01-01-19,A,X
01-01-19,A,Y
01-01-19,A,Z
02-01-19,A,X
02-01-19,A,Y
02-01-19,A,Z
02-01-19,A,W
01-01-19,B,X
01-01-19,B,Y
01-01-19,B,Z
02-01-19,B,X
02-01-19,B,X
02-01-19,B,Z
02-01-19,B,V
",sep = ",",strip.white = TRUE))
setnames(dt,c("date","group","value"))
Одним из решений было бы найти уникальные значения по группам. Затем просуммируйте уникальные значения по группе и дате.
## > dt[,dup:=!duplicated(value),.(group)][,sum(dup),.(group,date)]
## group date V1
## 1: A 01-01-19 3
## 2: A 02-01-19 1
## 3: B 01-01-19 3
## 4: B 02-01-19 1