您能帮我了解准报价的工作原理吗? 我正在使用 map 和计数功能,但它似乎无法正常工作。
第一次尝试:
map(names(starwars),~starwars %>% count(.x))
Error: Column `.x` is unknown
第二次尝试:
map(names(starwars),~starwars %>% count(!!.x))
#not useful [[1]]
# A tibble: 1 x 2
`"name"` n
<chr> <int>
1 name 87
[[2]]
# A tibble: 1 x 2
`"height"` n
<chr> <int>
1 height 87
第三次尝试:
map(names(starwars),~starwars %>% count(!!!.x))
# the same
另一个例子(处理函数):
如果我想创建一个接受列表和 相对于前一个元素更改列表中的每个元素 在该列表中:
my_list <- list("a" =1 , "b" = 2, "c" = 3)
# this obviously is not working (list + number)
> my_list+1
Error in my_list + 1 : non-numeric argument to binary operator
# this is a bit strange
my_list %>% map(~+1)
#this works fine
my_list %>% map(+1)
# as this
my_list %>% map(~.x+1)
# moving on to add the previous element to the next element
imap(my_list, my_list[[.y +1]] := .x %>% +1)
Error in `:=`(my_list[[.y + 1]], .x %>% +1) : could not find function ":="
# wrong eval 1?
imap(my_list, my_list[[.y +1]] <- .x %>% +1)
Error in eval(lhs, parent, parent) : object '.x' not found
# wrong eval 2?
imap(my_list, my_list[[.y +1]] <- !!.x %>% +1)
Error in eval(lhs, parent, parent) : object '.x' not found
# wrong symbol 1?
imap(my_list, my_list[[.y +1]] = .x %>% +1)
Error: unexpected '=' in "imap(my_list, my_list[[.y +1]] ="
最佳答案
我认为这个问题可以分解为准引用部分和 map
函数部分。
首先,~ starwars %>% count(.x))
是 function(.x){starwars %>% count(.x) 的简写形式,也是稍微复杂一点的版本)}
。所以我将直接使用这些函数。
其次,names(starwars)
为您提供一个字符向量。
因此,为了避免 map
带来的困惑,让我们从函数开始,并向它们传递字符“eye_color”。
尝试 1:dplyr
函数将符号视为表中的列
dplyr
函数在进行交互式数据分析时非常有用,因为它们允许我们使用符号引用列。我建议阅读:
https://dplyr.tidyverse.org/articles/programming.html了解更多信息。
func <- function(.x) { starwars %>% count(.x) }
func("eye_color")
Error: Column `.x` is unknown
在你的第一次尝试中,这会导致一个问题,因为 .x
是符号,所以 R 认为 .x
是 starwars
中的列.
尝试 2/3:count()
/group_by()
期望符号而不是字符输入。
!!
采用 .x
并将其替换为“eye_color”。但“eye_color”不是符号/名称,而是一个字符。
func_2 <- function(.x) { starwars %>% count(!!.x) }
func_2("eye_color")
# A tibble: 1 x 2
`"eye_color"` n
<chr> <int>
1 eye_color 87
这个奇怪的输出是按字符分组的结果。无论出于何种原因,dplyr
将整个数据帧分组为“eye_color”,然后告诉您有 87 行。 starwars %>% count("hooray")
给出类似的输出。
插曲:我们想要的是一个符号
编码 dplyr
函数的一种直观方法是传递符号/名称并使用 {{.x}}
来评估 promise 。 (不太直观,您可以执行 !!enquo(.x)
。)
func_3 <- function(.x) { starwars %>% count({{.x}}) }
func_3(eye_color)
# A tibble: 15 x 2
eye_color n
<chr> <int>
1 black 10
2 blue 19
3 ...
这有效!
解决方案是将字符转换为符号
func_4 <- function(.x) { .x = as.symbol(.x)
starwars %>% count({{.x}}) }
func_4("eye_color")
# A tibble: 15 x 2
eye_color n
<chr> <int>
1 black 10
2 blue 19
3 ...
这也有效!
带回 map
在继续之前,我认为 nniloc 的解决方案更适合您的问题。
但是你可以按如下方式使用 map
starwars %>%
select_if(negate(is.list)) %>%
names() %>%
map(function(.x) {x = as.symbol(.x)
starwars %>% count( {{ x }} )
})
或
starwars %>%
select_if(negate(is.list)) %>%
names() %>%
map(as.symbol) %>%
map(function(.x) {
starwars %>% count( {{ .x }} )
})
当您使用~
表示法时,.x
现在是直接引用符号的“代词”,因此我们可以使用!!
直接访问符号。 (我不太明白这一点)。
starwars %>%
select_if(negate(is.list)) %>%
names() %>%
map(as.symbol) %>%
map(~ starwars %>% count( !! .x ))
关于imap()
,看起来您想用Python(或其他带有迭代的语言)进行编码。 imap()
是 map2(.x, names(.x), ...)
的简写,因此与 enumerate()
不同在Python中。有像 seq_along
这样的 R 函数可以给你在对象中的位置,但我还没有将它们与 map 一起使用。
关于r - 使用列名执行 `map` 时如何使用准引用/整洁评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61139475/