tilde运算符在R中用于连接paste0()函数的目的是什么?

huangapple go评论88阅读模式
英文:

What is the purpose of the tilde operator when used to append the paste0() function in R?

问题

以下是翻译好的部分:

不加波浪号时,代码如下:

  1. betterLifeIndicators <- betterLifeIndicators |>
  2. rename_with(paste0(.x, "&quot;))

不起作用,并报告未找到对象'.x'。但是,当在paste0之前添加波浪号时,代码如下:

  1. betterLifeIndicators <- betterLifeIndicators |>
  2. rename_with(~paste0(.x, "&quot;))

它可以正常工作。我对R相当新手,难以理解这里的机制。我不确定整个行:

  1. rename_with(~paste0(.x, "&quot;))

如何实现其目的(在数据框的每个列名后附加括号)。

英文:

I am unsure as to how exactly the following line of code works, given that without the tilde:

  1. betterLifeIndicators &lt;- betterLifeIndicators |&gt;
  2. rename_with(paste0(.x, &quot;)&quot;))

it doesn't work, citing that the object '.x' is not found. Yet when adding the tilde in front of paste0:

  1. betterLifeIndicators &lt;- betterLifeIndicators |&gt;
  2. rename_with(~paste0(.x, &quot;)&quot;))

it works perfectly. I am quite new to R and I am struggling to understand the mechanism at work here. I am unsure as to how that whole line:

  1. rename_with(~paste0(.x, &quot;)&quot;))

is achieving its purpose (appending a parenthesis to every column name in a data.frame).

This is a flaw in my understanding of R, but I would appreciate any help with understanding this whole situation since I would hate to move forward with my project while leaving such a hole in my understanding of the language.

答案1

得分: 1

这是一些关于tidyverse的内容,其中介绍了R中的"formula"对象和"rename_with()"函数的用法。这个函数需要传递至少两个参数:1) 一个数据框(data.frame),2) 一个用于重命名列的函数。 "rename_with()" 函数会将第二个参数转化为一个函数,可以通过传递自定义函数来实现相同的效果。

英文:

Eh, this is some tidyverse jungle, but you can try to think about it like so:

In standard R there is a type of object called "formula" which is created with a tilde like so:

  1. f &lt;- ~ anythinig + can + be + here + paste(1, 2, 3)

We can check what is the class of this object and we get:

  1. &gt; class(f)
  2. [1] formula

Then, rename_with() is a function. It needs to be passed at least 2 arguments: 1) a data.frame, 2) a function that renames the columns:

  1. &gt; rename_with(iris, toupper)
  2. SEPAL.LENGTH SEPAL.WIDTH PETAL.LENGTH PETAL.WIDTH SPECIES
  3. 1 5.1 3.5 1.4 0.2 setosa
  4. 2 4.9 3.0 1.4 0.2 setosa
  5. 3 4.7 3.2 1.3 0.2 setosa
  6. 4 4.6 3.1 1.5 0.2 setosa
  7. 5 5.0 3.6 1.4 0.2 setosa
  8. 6 5.4 3.9 1.7 0.4 setosa

In R functions can choose what to do with their arguments. We can try to inspect what this particular function does:

  1. &gt; rename_with
  2. function (.data, .fn, .cols = everything(), ...)
  3. {
  4. UseMethod(&quot;rename_with&quot;)
  5. }
  6. &lt;bytecode: 0x7faad65f8510&gt;
  7. &lt;environment: namespace:dplyr&gt;

Not that useful, it tells us that this function is a generic function, the real body of it is hidden in some other place. We can find it here:

  1. &gt; dplyr:::rename_with.data.frame
  2. function (.data, .fn, .cols = everything(), ...)
  3. {
  4. .fn &lt;- as_function(.fn)
  5. cols &lt;- tidyselect::eval_select(enquo(.cols), .data, allow_rename = FALSE)
  6. names &lt;- names(.data)
  7. ...

Now we see that the first step it does to the second argument (.fn) is transform it into a function with as_function(.fn).

This as_function() function is in another tidyverse package - "rlang" and we can find it there:

  1. &gt; rlang::as_function
  2. function (x, env = global_env(), ..., arg = caller_arg(x), call = caller_env())
  3. {
  4. check_dots_empty0(...)
  5. if (is_function(x)) {
  6. return(x)
  7. }
  8. if (is_quosure(x)) {
  9. mask &lt;- eval_tidy(call2(environment), env = quo_get_env(x))
  10. fn &lt;- new_function(pairlist2(... = ), quo_get_expr(x), mask)
  11. return(fn)
  12. }
  13. if (is_formula(x)) {
  14. if (length(x) &gt; 2) {
  15. ...

The relevant part for us is this is_formula call in the end of the part of output I showed. So basically rename_with has some clever(?) way to turn a formula into a function. But you can achieve the same thing by passing your own function:

  1. iris |&gt; rename_with(function(x) paste0(x, &quot;)&quot;))
  2. Sepal.Length) Sepal.Width) Petal.Length) Petal.Width) Species)
  3. 1 5.1 3.5 1.4 0.2 setosa
  4. 2 4.9 3.0 1.4 0.2 setosa
  5. 3 4.7 3.2 1.3 0.2 setosa
  6. 4 4.6 3.1 1.5 0.2 setosa
  7. 5 5.0 3.6 1.4 0.2 setosa
  8. 6 5.4 3.9 1.7 0.4 setosa

The approach with tilde (creating a formula that is then turned into a function within rename_with) is just some syntax sugar. Under the hood the code then turns this formula into a function.

And your first approach:

  1. betterLifeIndicators &lt;- betterLifeIndicators |&gt;
  2. rename_with(paste0(.x, &quot;)&quot;))

didn't work, because in your call the argument paste0(.x, &quot;)&quot;) is not yet in a final form - it needs to be evaluated, R interpreter tries to evaluate this statement first but fails to find .x and shows you an error.

huangapple
  • 本文由 发表于 2023年4月7日 01:14:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定