R:过滤并在数据框中的数百行的列中添加重复的相同值
R: Filtering and adding a repeating identical value in a column for hundreds of rows in a dataframe
问题:
我有一个包含 16000 行 的数据框,我将使用此数据在 QGIS[=38= 中绘制一条船轨迹线].其中一列称为'Course',这是每个野外季节船出海的后续编号顺序。
例如,课程 1 的范围是 6/16/17 到 8/13/17。船轨数据框有五列,分别为 ID、日期、时间、航线、纬度和经度。这些值在每天 每秒 记录一次,通常在 早上 6 点到下午 6 点 之间。因此,对于每个野外课程,有数百行。在 5 年的时间内(2016-2018)总共有 11 门课程。
有什么方法可以按日期过滤每行数据以输入重复数字,例如 '2'(课程 2) 中的值 [=26] =]'Course' 列为日期 8/14/17 至 10/16/17,重复值“3”(课程 3)为日期 10/17/17 至03/01/18,等等?
不幸的是,我无法共享我的数据,也找不到 public 任何类似于我的数据框的数据,我可以使用函数 dput()[=38= 为这个问题提供这些数据].
我一直在使用 dplyr 和 tidyverse 等软件包来尝试解决这个难题,但到目前为止我没有成功找到一个解决方案。
有人能帮忙吗?
非常感谢。
如前所述,为此类内容编写示例数据很有帮助。在这里,我创建了 2 data.frames。一个将包含您的数据(16k 行),第二个将包含您的过滤条件(例如,您要保留的课程和日期范围)。
df1 <- data.frame(
ID = 1:10,
date = seq.Date(as.Date("2016-01-01"), as.Date("2019-01-01"), by = 120),
course = rep(1:5, each = 2)
)
df1
ID date course
1 1 2016-01-01 1
2 2 2016-04-30 1
3 3 2016-08-28 2
4 4 2016-12-26 2
5 5 2017-04-25 3
6 6 2017-08-23 3
7 7 2017-12-21 4
8 8 2018-04-20 4
9 9 2018-08-18 5
10 10 2018-12-16 5
df2 <- data.frame(
course = c(2, 3),
start_date = as.Date(c("2016-01-01", "2017-05-09")),
end_date = as.Date(c("2016-12-01", "2018-09-09"))
)
df2
course start_date end_date
1 2 2016-01-01 2016-12-01
2 3 2017-05-09 2018-09-09
他们没有所有的专栏,但希望这会给您带来灵感。
在我的示例中,我将过滤 df1
其中:
- 课程是 2,日期在 1/1/16 和 12/1/16 之间
- 课程是 3,日期在 5/9/17 和 9/9/18 之间
一旦你有了它,你可以尝试使用 fuzzyjoin
包来合并两者,使用 fuzzy_semi_join
。它将在第一个数据框中保留与第二个数据框中的条件匹配的行。
library(fuzzyjoin)
fuzzy_semi_join(
df1,
df2,
by = c("course", "date" = "start_date", "date" = "end_date"),
match_fun = c(`==`, `>=`, `<=`)
)
输出
ID date course
3 3 2016-08-28 2
6 6 2017-08-23 3
在这种情况下,只有两行符合这些条件。
作为替代方案,您可以使用 data.table
包进行合并。这可能是一个更快的解决方案。它应该给你相同的结果。
library(data.table)
setDT(df1)
setDT(df2)
df1[df2, .(ID, x.date, course), on = .(course, date >= start_date, date <= end_date)]
问题:
我有一个包含 16000 行 的数据框,我将使用此数据在 QGIS[=38= 中绘制一条船轨迹线].其中一列称为'Course',这是每个野外季节船出海的后续编号顺序。
例如,课程 1 的范围是 6/16/17 到 8/13/17。船轨数据框有五列,分别为 ID、日期、时间、航线、纬度和经度。这些值在每天 每秒 记录一次,通常在 早上 6 点到下午 6 点 之间。因此,对于每个野外课程,有数百行。在 5 年的时间内(2016-2018)总共有 11 门课程。
有什么方法可以按日期过滤每行数据以输入重复数字,例如 '2'(课程 2) 中的值 [=26] =]'Course' 列为日期 8/14/17 至 10/16/17,重复值“3”(课程 3)为日期 10/17/17 至03/01/18,等等?
不幸的是,我无法共享我的数据,也找不到 public 任何类似于我的数据框的数据,我可以使用函数 dput()[=38= 为这个问题提供这些数据].
我一直在使用 dplyr 和 tidyverse 等软件包来尝试解决这个难题,但到目前为止我没有成功找到一个解决方案。
有人能帮忙吗?
非常感谢。
如前所述,为此类内容编写示例数据很有帮助。在这里,我创建了 2 data.frames。一个将包含您的数据(16k 行),第二个将包含您的过滤条件(例如,您要保留的课程和日期范围)。
df1 <- data.frame(
ID = 1:10,
date = seq.Date(as.Date("2016-01-01"), as.Date("2019-01-01"), by = 120),
course = rep(1:5, each = 2)
)
df1
ID date course
1 1 2016-01-01 1
2 2 2016-04-30 1
3 3 2016-08-28 2
4 4 2016-12-26 2
5 5 2017-04-25 3
6 6 2017-08-23 3
7 7 2017-12-21 4
8 8 2018-04-20 4
9 9 2018-08-18 5
10 10 2018-12-16 5
df2 <- data.frame(
course = c(2, 3),
start_date = as.Date(c("2016-01-01", "2017-05-09")),
end_date = as.Date(c("2016-12-01", "2018-09-09"))
)
df2
course start_date end_date
1 2 2016-01-01 2016-12-01
2 3 2017-05-09 2018-09-09
他们没有所有的专栏,但希望这会给您带来灵感。
在我的示例中,我将过滤 df1
其中:
- 课程是 2,日期在 1/1/16 和 12/1/16 之间
- 课程是 3,日期在 5/9/17 和 9/9/18 之间
一旦你有了它,你可以尝试使用 fuzzyjoin
包来合并两者,使用 fuzzy_semi_join
。它将在第一个数据框中保留与第二个数据框中的条件匹配的行。
library(fuzzyjoin)
fuzzy_semi_join(
df1,
df2,
by = c("course", "date" = "start_date", "date" = "end_date"),
match_fun = c(`==`, `>=`, `<=`)
)
输出
ID date course
3 3 2016-08-28 2
6 6 2017-08-23 3
在这种情况下,只有两行符合这些条件。
作为替代方案,您可以使用 data.table
包进行合并。这可能是一个更快的解决方案。它应该给你相同的结果。
library(data.table)
setDT(df1)
setDT(df2)
df1[df2, .(ID, x.date, course), on = .(course, date >= start_date, date <= end_date)]