Создание переменной на основе условий сопоставления в двух наборах данных - PullRequest
0 голосов
/ 13 октября 2019

Я пытаюсь создать переменную в одном длинном наборе данных (df1), где значение в каждой строке должно основываться на сопоставлении некоторых условий в другом длинном наборе данных (df2). Условия: - совпадение по «имени» - значение для df1 должно учитывать наблюдения для этого человека, которые произошли до наблюдения в df1. - Затем мне нужно количество строк в этом подмножестве, которые удовлетворяют третьему условию (в данных ниже, называемых «условием»)

Я уже пытался запустить цикл for (я знаю, не рекомендуется в R)записать это для каждой строки в 1: nrow (df1), но я продолжаю сталкиваться с проблемой, что в моих реальных данных df1 и df2 не имеют одинаковую длину или кратные.

Я также пытался написать функцию и применить ее к df1. Я попытался применить его с помощью apply, но я не могу принять два кадра данных в синтаксисе apply. Я попытался дать ему список данных и использовать lapply, но он возвращает нулевые значения.

Вот некоторые общие данные, которые соответствуют формату данных, с которыми я работаю.

df1 <- data.frame(
  name = c("John Smith", "John Smith", "Jane Smith", "Jane Smith"),
  date_b = sample(seq(as.Date('2014/01/01'), as.Date('2019/10/01'), by="day"), 4))

df2 <- data.frame(
  name = c("John Smith", "John Smith", "Jane Smith", "Jane Smith"),
  date_a = sample(seq(as.Date('2014/01/01'), as.Date('2019/10/01'), by="day"), 4),
  condition = c("A", "B", "C", "A")
)

Я знаю, что способ получения количества строк может выглядеть примерно так:

num_conditions <- nrow(df2[which(df1$nam== df2$name & df2$date_a < df1$date_b & df2$condition == "A"), ])

То, что я хотел бы видеть в df1, это столбец с именем "num_conditions"«это показало бы число наблюдений в df2 для этого человека, которые произошли до date_b в df1 и выполнили условие« A ».

df1 должно выглядеть следующим образом:

name          date_b    num_conditions
John Smith    10/1/15           1
John Smith    11/15/16          0
John Smith    9/19/19           0

Ответы [ 2 ]

0 голосов
/ 13 октября 2019

Возможно, вот что задаёт вопрос:

library(tidyverse)

df1 %>%
  left_join(df2 %>% filter(condition == 'A'), by = 'name') %>%
  filter(date_a < date_b) %>%
  group_by(name) %>%
  mutate(num_conditions = n()) %>%
  select(-date_a, -condition) %>%
  full_join(df1) %>%
  mutate(num_conditions = ifelse(is.na(num_conditions), 0, num_conditions))
#Joining, by = c("name", "date_b")
## A tibble: 4 x 3
## Groups:   name [2]
#  name       date_b     num_conditions
#  <fct>      <date>              <dbl>
#1 John Smith 2019-05-07              2
#2 John Smith 2019-02-05              2
#3 Jane Smith 2016-05-03              0
#4 Jane Smith 2018-06-23              0
0 голосов
/ 13 октября 2019

Я уверен, что есть лучшие способы, включая data.table, но вот один, использующий dplyr:

library(dplyr)

set.seed(12)

df2 %>%
  filter(condition == "A") %>%
  right_join(df1, by = "name") %>%
  group_by(name, date_b) %>%
  filter(date_a < date_b) %>%
  mutate(num_conditions = n()) %>%
  right_join(df1, by = c("name", "date_b")) %>%
  mutate(num_conditions = coalesce(num_conditions, 0L)) %>%
  select(-c(date_a, condition)) %>%
  distinct()

# A tibble: 4 x 3
# Groups:   name, date_b [4]
  name       date_b     num_conditions
  <fct>      <date>              <int>
1 John Smith 2016-10-13              2
2 John Smith 2015-11-10              2
3 Jane Smith 2016-07-18              1
4 Jane Smith 2018-03-13              1

R> df1
        name     date_b
1 John Smith 2016-10-13
2 John Smith 2015-11-10
3 Jane Smith 2016-07-18
4 Jane Smith 2018-03-13

R> df2
        name     date_a condition
1 John Smith 2015-04-16         A
2 John Smith 2014-09-27         A
3 Jane Smith 2017-04-25         C
4 Jane Smith 2015-08-20         A
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...