R:在 sapply、lapply 和 mapply 上使用 match.fun
R: use of match.fun over sapply, lapply and mapply
我不确定我对 match.fun 的用法对这种情况是否正确。 (我不想使用for循环,因为它需要时间)。
我有一个这样的数据框。
df <- data.frame(client = c("A", "B", "C", "D"),
fun = c("bill1stEvent_OT", "bill1stEvent_Tour", "billCreation_OT", "bill1stEvent_Tour_LoadingSite"),
agency = c("NA", "NA", "Agency_A", "NA"),
loading_site = c("NA", "NA", "NA", "Paris"))
>df
client fun agency loading_site
A bill1stEvent_OT NA NA
B bill1stEvent_Tour NA NA
C billCreation_OT Agency_A NA
D bill1stEvent_Tour_LoadingSite NA Paris
fun
列包含我创建的函数。每个函数都采用相同的参数:client
、agency
、loading_site
、year
和 month
。因此,您阅读此 table 的方式是,例如,对于客户端 C
,应用带有参数 agency = Agency_A
和 loading_site = NULL
的函数 billCreation_OT
。每个函数returns一个数据框。
我有一个要应用函数的客户端列表,我还设置了参数 year
和 month
。 :
client_list <- c("A", "C")
year <- "2018"
month <- "07"
问题:如何调用此 table 并仅使用 "one go" 应用具有相应参数的函数?因此,对于上面的 client_list
,我想做的是 运行 下面的这两个函数,并将结果(数据帧)存储在列表(或任何可能的)中。
bill1stEvent_OT(client = "A", agency = NULL, loading_site = NULL)
billCreation_OT(client = "C", agency = Agency_A, loading_site = NULL)
我的尝试:
fun_to_apply <- df[df$client %in% client_list, ]$fun
agency_arg <- df[df$client %in% client_list, ]$agency
loading_site_arg <- df[df$client %in% client_list, ]$loading_site
sapply(X = lapply(fun_to_apply, match.fun),
FUN = mapply,
year = year,
month = month,
agency = agency_arg,
loading_site = loading_site_arg)
Error in (function (client, year, month) :
arguments inutilisés (agency = dots[[3]][[1]], loading_site = dots[[4]][[1]])
我也不知道如何将参数 agency
和 loading_site
作为 NULL
传递给函数参数。当您读取数据框时,它会将 NA
评估为像 "NA"
我猜的字符串。
感谢您的帮助!
我创建了一些打印参数的示例函数:
bill1stEvent_OT <- function(...) {
print("bill1stEvent_OT")
lapply(list(...), print)
cat("\n")
}
billCreation_OT <- function(...) {
print("bill1stEvent_OT")
lapply(list(...), print)
cat("\n")
}
而且我认为您正在寻找的是类似的东西(get 等同于 match.fun):
apply(df[df$client %in% client_list,], 1,
function(x) get(x["fun"])(x["agency"], x["loading_site"]))
[1] "bill1stEvent_OT"
agency
"NA"
loading_site
"NA"
[1] "bill1stEvent_OT"
agency
"Agency_A"
loading_site
"NA"
NULL
最终您可以使用 mapply()
和 do.call()
:
D <- read.table(header=TRUE, stringsAsFactors = FALSE, text=
"fun a b
+ 3 5
- 8 2
* 4 4
+ 1 NA"
)
myfu <- function(fun, a, b) do.call(fun, list(a=a, b=b))
mapply(myfu, D$fun, D$a, D$b)
或
unlist(Map(myfu, D$f, D$a, D$b))
为了说明我的 "can be done" 评论:
# inputs
client_list <- c("A", "C")
year <- "2018"
month <- "07"
# dummy functions
bill1stEvent_OT <- function(agency, loading_site){paste("11", year, month, agency, loading_site)}
bill1stEvent_Tour <- function(agency, loading_site){paste("22", year, month, agency, loading_site)}
billCreation_OT <- function(agency, loading_site){paste("33", year, month, agency, loading_site)}
bill1stEvent_Tour_LoadingSite <- function(agency, loading_site){paste("44", year, month, agency, loading_site)}
# loop through rows, match function name
apply(df, 1, function(i){
# we can add a step to convert "NA" to actual NA.
if(i[1] %in% client_list){
match.fun(i[2])(agency = i[3], loading_site = i[4])
} else {NA}
})
# [1] "11 2018 07 NA NA" NA "33 2018 07 Agency_A NA" NA
已经展示了可能的方式,我不推荐使用这个。如果您能告诉我们更多有关问题的信息,还有更好的方法。
我不确定我对 match.fun 的用法对这种情况是否正确。 (我不想使用for循环,因为它需要时间)。
我有一个这样的数据框。
df <- data.frame(client = c("A", "B", "C", "D"),
fun = c("bill1stEvent_OT", "bill1stEvent_Tour", "billCreation_OT", "bill1stEvent_Tour_LoadingSite"),
agency = c("NA", "NA", "Agency_A", "NA"),
loading_site = c("NA", "NA", "NA", "Paris"))
>df
client fun agency loading_site
A bill1stEvent_OT NA NA
B bill1stEvent_Tour NA NA
C billCreation_OT Agency_A NA
D bill1stEvent_Tour_LoadingSite NA Paris
fun
列包含我创建的函数。每个函数都采用相同的参数:client
、agency
、loading_site
、year
和 month
。因此,您阅读此 table 的方式是,例如,对于客户端 C
,应用带有参数 agency = Agency_A
和 loading_site = NULL
的函数 billCreation_OT
。每个函数returns一个数据框。
我有一个要应用函数的客户端列表,我还设置了参数 year
和 month
。 :
client_list <- c("A", "C")
year <- "2018"
month <- "07"
问题:如何调用此 table 并仅使用 "one go" 应用具有相应参数的函数?因此,对于上面的 client_list
,我想做的是 运行 下面的这两个函数,并将结果(数据帧)存储在列表(或任何可能的)中。
bill1stEvent_OT(client = "A", agency = NULL, loading_site = NULL)
billCreation_OT(client = "C", agency = Agency_A, loading_site = NULL)
我的尝试:
fun_to_apply <- df[df$client %in% client_list, ]$fun
agency_arg <- df[df$client %in% client_list, ]$agency
loading_site_arg <- df[df$client %in% client_list, ]$loading_site
sapply(X = lapply(fun_to_apply, match.fun),
FUN = mapply,
year = year,
month = month,
agency = agency_arg,
loading_site = loading_site_arg)
Error in (function (client, year, month) :
arguments inutilisés (agency = dots[[3]][[1]], loading_site = dots[[4]][[1]])
我也不知道如何将参数 agency
和 loading_site
作为 NULL
传递给函数参数。当您读取数据框时,它会将 NA
评估为像 "NA"
我猜的字符串。
感谢您的帮助!
我创建了一些打印参数的示例函数:
bill1stEvent_OT <- function(...) {
print("bill1stEvent_OT")
lapply(list(...), print)
cat("\n")
}
billCreation_OT <- function(...) {
print("bill1stEvent_OT")
lapply(list(...), print)
cat("\n")
}
而且我认为您正在寻找的是类似的东西(get 等同于 match.fun):
apply(df[df$client %in% client_list,], 1,
function(x) get(x["fun"])(x["agency"], x["loading_site"]))
[1] "bill1stEvent_OT"
agency
"NA"
loading_site
"NA"
[1] "bill1stEvent_OT"
agency
"Agency_A"
loading_site
"NA"
NULL
最终您可以使用 mapply()
和 do.call()
:
D <- read.table(header=TRUE, stringsAsFactors = FALSE, text=
"fun a b
+ 3 5
- 8 2
* 4 4
+ 1 NA"
)
myfu <- function(fun, a, b) do.call(fun, list(a=a, b=b))
mapply(myfu, D$fun, D$a, D$b)
或
unlist(Map(myfu, D$f, D$a, D$b))
为了说明我的 "can be done" 评论:
# inputs
client_list <- c("A", "C")
year <- "2018"
month <- "07"
# dummy functions
bill1stEvent_OT <- function(agency, loading_site){paste("11", year, month, agency, loading_site)}
bill1stEvent_Tour <- function(agency, loading_site){paste("22", year, month, agency, loading_site)}
billCreation_OT <- function(agency, loading_site){paste("33", year, month, agency, loading_site)}
bill1stEvent_Tour_LoadingSite <- function(agency, loading_site){paste("44", year, month, agency, loading_site)}
# loop through rows, match function name
apply(df, 1, function(i){
# we can add a step to convert "NA" to actual NA.
if(i[1] %in% client_list){
match.fun(i[2])(agency = i[3], loading_site = i[4])
} else {NA}
})
# [1] "11 2018 07 NA NA" NA "33 2018 07 Agency_A NA" NA
已经展示了可能的方式,我不推荐使用这个。如果您能告诉我们更多有关问题的信息,还有更好的方法。