如何跨多个列表应用具有多个变量的函数
How to mapply a function with multiple variables across multiple lists
我有点不懂 mapply() 和 do.call...
所以我有两个这样的列表:
ID START END
a1 1/1/2000 1/30/2000
a2 5/4/2000 3/1/2002
a3 5/8/2004 8/7/2005
a4 1/3/2012 5/7/2015
ID START END
b1 5/1/2000 1/30/2020
b2 6/4/2007 3/1/2008
b3 5/8/2014 8/7/2015
b4 1/3/1999 5/7/2019
许多日期相互重叠,这就是我要确定的。我正在尝试为第二个列表中的每个条目创建一个列到第一个列表中,说明日期范围是否重叠...
ID START END b1 b2 b3 b4
a1 1/1/2000 1/30/2000 0 0 0 1
a2 5/4/2000 3/1/2002 1 0 0 1
a3 5/8/2004 8/7/2005 1 0 0 1
a4 1/3/2012 5/7/2015 1 0 1 1
其中 0 表示不重叠事件,1 表示重叠。
到目前为止,我的努力是在具有多个变量的函数中使用 dplyr mutate。然后我尝试使用 mapply 将整个列表作为这些变量输入...
builder <- function(id,start,finish){
resource_const_all <- resource_const %>%
mutate(id = ifelse(start > START & start < END,"1",
ifelse(finish > START & finish < END, "1",
ifelse(start < START & finish > END, "1", "0"))))
}
###if the start date falls in the date range, it returns 1.
###if the end date falls in the date range, it returns 1.
###if the start date is before the date range and the end date is after, it
###returns 1.
###Else the dates don't overlap, returns 0.
builder_output <- mapply(builder,id_list,start_list,end_list))
感谢您的帮助!
假设末尾注释中显示的数据可重现,我们确保 START
和 END
列属于 Date
class。然后如图所示使用 outer
。
请注意 overlap
是通用测试,overlapAB
使其特定于 A
和 B
。
没有使用包。
overlap <- function(start1, end1, start2, end2) {
(start1 >= start2 & start1 <= end2) | (start2 >= start1 & start2 <= end1)
}
overlapAB <- function(idA, idB) {
i <- match(idA, A$ID)
j <- match(idB, B$ID)
overlap(A$START[i], A$END[i], B$START[j], B$END[j])
}
cbind(A, +outer(A$ID, B$ID, overlapAB))
给予:
ID START END b1 b2 b3 b4
1 a1 2000-01-01 2000-01-30 0 0 0 1
2 a2 2000-05-04 2002-03-01 1 0 0 1
3 a3 2004-05-08 2005-08-07 1 0 0 1
4 a4 2012-01-03 2015-05-07 1 0 1 1
备注
LinesA <- "ID START END
a1 1/1/2000 1/30/2000
a2 5/4/2000 3/1/2002
a3 5/8/2004 8/7/2005
a4 1/3/2012 5/7/2015"
LinesB <- "ID START END
b1 5/1/2000 1/30/2020
b2 6/4/2007 3/1/2008
b3 5/8/2014 8/7/2015
b4 1/3/1999 5/7/2019"
fmt <- "%m/%d/%Y"
A <- read.table(text = LinesA, header = TRUE, as.is = TRUE)
A$START <- as.Date(A$START, fmt)
A$END <- as.Date(A$END, fmt)
B <- read.table(text = LinesB, header = TRUE, as.is = TRUE)
B$START <- as.Date(B$START, fmt)
B$END <- as.Date(B$END, fmt)
我有点不懂 mapply() 和 do.call...
所以我有两个这样的列表:
ID START END
a1 1/1/2000 1/30/2000
a2 5/4/2000 3/1/2002
a3 5/8/2004 8/7/2005
a4 1/3/2012 5/7/2015
ID START END
b1 5/1/2000 1/30/2020
b2 6/4/2007 3/1/2008
b3 5/8/2014 8/7/2015
b4 1/3/1999 5/7/2019
许多日期相互重叠,这就是我要确定的。我正在尝试为第二个列表中的每个条目创建一个列到第一个列表中,说明日期范围是否重叠...
ID START END b1 b2 b3 b4
a1 1/1/2000 1/30/2000 0 0 0 1
a2 5/4/2000 3/1/2002 1 0 0 1
a3 5/8/2004 8/7/2005 1 0 0 1
a4 1/3/2012 5/7/2015 1 0 1 1
其中 0 表示不重叠事件,1 表示重叠。
到目前为止,我的努力是在具有多个变量的函数中使用 dplyr mutate。然后我尝试使用 mapply 将整个列表作为这些变量输入...
builder <- function(id,start,finish){
resource_const_all <- resource_const %>%
mutate(id = ifelse(start > START & start < END,"1",
ifelse(finish > START & finish < END, "1",
ifelse(start < START & finish > END, "1", "0"))))
}
###if the start date falls in the date range, it returns 1.
###if the end date falls in the date range, it returns 1.
###if the start date is before the date range and the end date is after, it
###returns 1.
###Else the dates don't overlap, returns 0.
builder_output <- mapply(builder,id_list,start_list,end_list))
感谢您的帮助!
假设末尾注释中显示的数据可重现,我们确保 START
和 END
列属于 Date
class。然后如图所示使用 outer
。
请注意 overlap
是通用测试,overlapAB
使其特定于 A
和 B
。
没有使用包。
overlap <- function(start1, end1, start2, end2) {
(start1 >= start2 & start1 <= end2) | (start2 >= start1 & start2 <= end1)
}
overlapAB <- function(idA, idB) {
i <- match(idA, A$ID)
j <- match(idB, B$ID)
overlap(A$START[i], A$END[i], B$START[j], B$END[j])
}
cbind(A, +outer(A$ID, B$ID, overlapAB))
给予:
ID START END b1 b2 b3 b4
1 a1 2000-01-01 2000-01-30 0 0 0 1
2 a2 2000-05-04 2002-03-01 1 0 0 1
3 a3 2004-05-08 2005-08-07 1 0 0 1
4 a4 2012-01-03 2015-05-07 1 0 1 1
备注
LinesA <- "ID START END
a1 1/1/2000 1/30/2000
a2 5/4/2000 3/1/2002
a3 5/8/2004 8/7/2005
a4 1/3/2012 5/7/2015"
LinesB <- "ID START END
b1 5/1/2000 1/30/2020
b2 6/4/2007 3/1/2008
b3 5/8/2014 8/7/2015
b4 1/3/1999 5/7/2019"
fmt <- "%m/%d/%Y"
A <- read.table(text = LinesA, header = TRUE, as.is = TRUE)
A$START <- as.Date(A$START, fmt)
A$END <- as.Date(A$END, fmt)
B <- read.table(text = LinesB, header = TRUE, as.is = TRUE)
B$START <- as.Date(B$START, fmt)
B$END <- as.Date(B$END, fmt)