首页 > 解决方案 > 如何使用 mutate 仅基于数据框其他行的子集创建新列?

问题描述

我正在为如何表达我的问题而苦恼。我有一个帐户数据框,我想创建一个新列,该列是一个标志,用于指示在该帐户的 30 天内是否有另一个帐户具有重复的电子邮件。

我有一张这样的桌子。

AccountNumbers <- c(3748,8894,9923,4502,7283,8012,2938,7485,1010,9877)
EmailAddress <- c("John@gmail.com","John@gmail.com","Alex@outlook.com","Alan@yahoo.com","Stan@aol.com","Mary@outlook.com","Adam@outlook.com","Tom@aol.com","Jane@yahoo.com","John@gmail.com")

Dates <- c("2018-05-01","2018-05-05","2018-05-10","2018-05-15","2018-05-20",
       "2018-05-25","2018-05-30","2018-06-01","2018-06-05","2018-06-10")

df <- data.frame(AccountNumbers,EmailAddress,Dates)

print(df)

AccountNumbers     EmailAddress      Dates
3748           John@gmail.com    2018-05-01
8894           John@gmail.com    2018-05-05
9923           Alex@outlook.com  2018-05-10
4502           Alan@yahoo.com    2018-05-15
7283           Stan@aol.com      2018-05-20
8012           Mary@outlook.com  2018-05-25
2938           Adam@outlook.com  2018-05-30
7485           Tom@aol.com       2018-06-01
1010           Jane@yahoo.com    2018-06-05
9877           John@gmail.com    2018-06-10 

John@gmail.com 出现了 3 次,我想标记前两行,因为它们都在 30 天内出现,但我不想标记第三行。

AccountNumbers     EmailAddress      Dates        DuplicateEmailFlag
3748           John@gmail.com    2018-05-01                  1
8894           John@gmail.com    2018-05-05                  1
9923           Alex@outlook.com  2018-05-10                  0
4502           Alan@yahoo.com    2018-05-15                  0
7283           Stan@aol.com      2018-05-20                  0
8012           Mary@outlook.com  2018-05-25                  0
2938           Adam@outlook.com  2018-05-30                  0
7485           Tom@aol.com       2018-06-01                  0
1010           Jane@yahoo.com    2018-06-05                  0
9877           John@gmail.com    2018-06-10                  0

我一直在尝试在 mutate 中使用 ifelse() ,但我不知道是否可以告诉 dplyr 只考虑在考虑行的 30 天内的行。

编辑:为了澄清,我想看看每个帐户周围的 30 天。因此,如果我有一个场景,即每 30 天恰好添加一次相同的电子邮件地址,则应标记该电子邮件的所有出现。

标签: rdplyr

解决方案


似乎有效。首先,我定义数据框。

AccountNumbers <- c(3748,8894,9923,4502,7283,8012,2938,7485,1010,9877)
EmailAddress <- c("John@gmail.com","John@gmail.com","Alex@outlook.com","Alan@yahoo.com","Stan@aol.com","Mary@outlook.com","Adam@outlook.com","Tom@aol.com","Jane@yahoo.com","John@gmail.com")

Dates <- c("2018-05-01","2018-05-05","2018-05-10","2018-05-15","2018-05-20",
           "2018-05-25","2018-05-30","2018-06-01","2018-06-05","2018-06-10")

df <- data.frame(number = AccountNumbers, email = EmailAddress, date = as.Date(Dates))

接下来,我通过电子邮件进行分组,并检查前 30 天或后 30 天内是否有条目。我还将NAs(对应于只有一个条目的情况)替换为 0。最后,我取消分组。

df %>% 
  group_by(email) %>% 
  mutate(dupe = coalesce(date - lag(date) < 30, (date - lead(date) < 30))) %>% 
  mutate(dupe = replace_na(dupe, 0)) %>% 
  ungroup

这给出了,

# # A tibble: 10 x 4
#    number email            date        dupe
#     <dbl> <fct>            <date>     <dbl>
#  1   3748 John@gmail.com   2018-05-01     1
#  2   8894 John@gmail.com   2018-05-05     1
#  3   9923 Alex@outlook.com 2018-05-10     0
#  4   4502 Alan@yahoo.com   2018-05-15     0
#  5   7283 Stan@aol.com     2018-05-20     0
#  6   8012 Mary@outlook.com 2018-05-25     0
#  7   2938 Adam@outlook.com 2018-05-30     0
#  8   7485 Tom@aol.com      2018-06-01     0
#  9   1010 Jane@yahoo.com   2018-06-05     0
# 10   9877 John@gmail.com   2018-06-10     0

按要求。


编辑:这隐含地假设您的数据按日期排序。如果没有,您需要添加一个额外的步骤来执行此操作。


推荐阅读