r - 如何使用 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 天恰好添加一次相同的电子邮件地址,则应标记该电子邮件的所有出现。
解决方案
这似乎有效。首先,我定义数据框。
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 天内是否有条目。我还将NA
s(对应于只有一个条目的情况)替换为 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
按要求。
编辑:这隐含地假设您的数据按日期排序。如果没有,您需要添加一个额外的步骤来执行此操作。
推荐阅读
- windows - 对于 FOR 循环中的目录,“%~zI”究竟是什么?
- sql-server - 执行 SQL 任务中的 SSIS 包错误单个更新
- reactjs - 使用 axios (react) 和 PHP 上传图片
- javascript - 如何为 javascript 变量分配坐标,并在这些变量周围使用 moveTo 和 lineTo 画线?
- c# - 使用 LINQ 从选定的 XML 元素填充 DataGridView
- node.js - 如何使用分离的前端(SPA React/React-Router)和后端(node.js)使用 openIDConnect 对用户进行身份验证?
- python - 将具有多个参数的函数应用于 pandas groupby 对象
- node.js - 使用“pm2 start”与 Express 应用程序反应总是显示错误状态
- c# - Python垂直数组?到 C#
- angular - 如何让 Angular 输入组件提交其数据?