gpt4 book ai didi

r - 在R中使用apply或map函数时如何将列名传递给函数?

转载 作者:行者123 更新时间:2023-12-04 07:16:14 26 4
gpt4 key购买 nike

我试图将多个函数应用于同一个数据帧,但我无法成功将列名作为参数传递,该参数使用 purrr::imap .但是,我不断收到以下错误:

Error in UseMethod("select") : no applicable method for 'select'applied to an object of class "character"


我已经尝试了我可以在 SO 上找到的所有组合(例如,使用 !!![[enquosys.lang 等等)。我可以得到 select当我将函数(例如, check_1 )直接应用于数据帧时起作用,但在使用 imap 时尝试将列名作为参数传递时不起作用和 exec 。列名的格式是问题的一部分(例如, 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代词。
最后,代替 select + unlist + as.vector你可以简单地使用 dplyr::pull :

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 - 在R中使用apply或map函数时如何将列名传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68737808/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com