在R中使用Apply或MAP函数时,如何将列名传递给函数? [英] How to pass column names into a function when using an apply or map function in R?
本文介绍了在R中使用Apply或MAP函数时,如何将列名传递给函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试将多个函数应用于同一个DataFrame,但我无法成功地将列名作为参数传递,该参数使用purrr::imap
。但是,我一直收到以下错误:
UseMethod(&QOOT;SELECT&QOOT;)中出错:没有适用于‘SELECT’的方法 应用于类&Character&Quot;的对象我尝试了在SO上找到的所有组合(例如,使用
!!!
、[[
、enquo
、sys.lang
等等)。当我将函数(例如,check_1
)直接应用于数据帧时,我可以使select
工作,但在使用imap
和exec
时尝试将列名作为参数传递时,我无法使select
工作。列名的格式是问题的一部分(例如,1.1.
),但尝试了引号和单引号等。
这是previous post的后续,但该帖子和解决方案侧重于将多个函数应用于各个列。现在,我需要应用多个函数,这些函数使用数据帧中的多个列;因此,需要在函数中指定列名。我确信有可能将其整合到另一个框架中,但我想先自己试一试。
最小示例
数据
df <- structure(
list(
`1.1.` = c("Andrew", "Max", "Sylvia", NA, "1",
NA, NA, "Jason"),
`1.2.` = c(1, 2, 2, NA, 4, 5, 3, NA),
`1.2.1.` = c(
"cool", "amazing", "wonderful", "okay",
NA, NA, "chocolate", "fine"
)
),
class = "data.frame",
row.names = c(NA, -8L)
)
我尝试的内容
library(purrr)
library(dplyr)
check_1 <- function(x, col1, col2) {
x %>%
dplyr::select(col1, col2) %>%
dplyr::mutate(row.index = row_number()) %>%
dplyr::filter(col1 == "Jason" & is.na(col2) == TRUE) %>%
dplyr::select(row.index) %>%
unlist() %>%
as.vector()
}
check_2 <- function(x, col1, col2) {
index <- x %>%
dplyr::select(col1, col2) %>%
dplyr::mutate(row.index = row_number()) %>%
dplyr::filter(col1 >= 3 & col1 <= 5 & is.na(col2) == TRUE) %>%
dplyr::select(row.index) %>%
unlist() %>%
as.vector()
return(index)
}
checks <-
list("df" = list(fn = check_1, pars = list(col1 = "1.1.", col2 = "1.2.")),
"df" = list(fn = check_2, pars = list(col1 = "1.2.", col2 = "1.2.1.")))
results <-
purrr::imap(checks, ~ exec(.x$fn, x = .y,!!!.x$pars))
预期输出
> results
$df
[1] 8
$df
[1] 5 6
除了";类字符错误外,当我尝试单独测试check_2
函数时,我还收到一个额外的错误,其中它不返回任何预期值。
[1] 1.2. 1.2.1. row.index
<0 rows> (or 0-length row.names)
我看过很多其他类似的so帖子(例如this one),但没有一个为我解决这个问题。
推荐答案
第一个问题是您传递的是数据帧的名称,而不是数据帧本身。这就是为什么当您尝试从字符串select
时收到第一个错误的原因。若要解决此问题,请将数据帧添加到您正在循环的列表中。
dplyr
这些字符引用数据中的列。这可以通过使用.data
代词来实现。
最后,您可以简单地使用dplyr::pull
:
select + unlist + as.vector
library(purrr)
library(dplyr)
check_1 <- function(x, col1, col2) {
x %>%
dplyr::select(all_of(c(col1, col2))) %>%
dplyr::mutate(row.index = row_number()) %>%
dplyr::filter(.data[[col1]] == "Jason" & is.na(.data[[col2]]) == TRUE) %>%
dplyr::pull(row.index)
}
check_2 <- function(x, col1, col2) {
x %>%
dplyr::select(all_of(c(col1, col2))) %>%
dplyr::mutate(row.index = row_number()) %>%
dplyr::filter(.data[[col1]] >= 3 & .data[[col1]] <= 5 & is.na(.data[[col2]]) == TRUE) %>%
dplyr::pull(row.index)
}
checks <-
list(df = list(df = df, fn = check_1, pars = list(col1 = "1.1.", col2 = "1.2.")),
df = list(df = df, fn = check_2, pars = list(col1 = "1.2.", col2 = "1.2.1.")))
purrr::map(checks, ~ exec(.x$fn, x = .x$df, !!!.x$pars))
#> $df
#> [1] 8
#>
#> $df
#> [1] 5 6
这篇关于在R中使用Apply或MAP函数时,如何将列名传递给函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文