简体   繁体   English

从 dplyr 中的变量中引用列名

[英]refer to column name from variable in across in dplyr

Given a reference column z , I want to use dplyr to transform each column as:给定参考列z ,我想使用dplyr将每一列转换为:

x = log(x) - log(z)

I want z to be a string, or even better, a quoted expression (eg input by a user - all of this is within a function).我希望z是一个字符串,或者更好的是,一个带引号的表达式(例如,由用户输入 - 所有这些都在一个函数内)。

Here is what I've tried:这是我尝试过的:

library(dplyr)
m <- data.frame(x=1:5,y=11:15,z=21:25)
denom = "z"

This works:这有效:

m %>%
        mutate(across(x:z ,
                list(~ log(.) - log(z) )))

This fails:这失败了:

m %>%
        mutate(across(x:z ,
                list(~ log(.) - log(rlang::sym(denom)))))

# Error: Problem with `mutate()` input `..1`.
# ℹ `..1 = across(x:z, list(~log(.) - log(rlang::sym(denom))))`.
# ✖ non-numeric argument to mathematical function
# Run `rlang::last_error()` to see where the error occurred.

This also fails:这也失败了:

m %>%
        mutate(across(x:z ,
                list(~ log(.) - log(!!denom) )))

# Error: Problem with `mutate()` input `..1`.
# ℹ `..1 = across(x:z, list(~log(.) - log("z")))`.
# ✖ non-numeric argument to mathematical function
# Run `rlang::last_error()` to see where the error occurred.
# >                 #list(~ log(.) - log(rlang::sym(denom)))))

您还可以使用get()

m %>% mutate(across(.fns = list(~ log(.) - log(get(denom)))))

Making use of the .data pronoun from rlang you could do:使用rlang中的.data代词,您可以:

library(dplyr)

m <- data.frame(x = 1:5, y = 11:15, z = 21:25)
denom <- "z"

m %>% mutate(across(
  x:z,
  list(~ log(.) - log(.data[[denom]]))
))
#>   x  y  z       x_1        y_1 z_1
#> 1 1 11 21 -3.044522 -0.6466272   0
#> 2 2 12 22 -2.397895 -0.6061358   0
#> 3 3 13 23 -2.036882 -0.5705449   0
#> 4 4 14 24 -1.791759 -0.5389965   0
#> 5 5 15 25 -1.609438 -0.5108256   0

I don't know, if this is a good way to code, but you can do我不知道,这是否是一种很好的编码方式,但你可以这样做

library(dplyr)

m %>%
  mutate(across(x:z ,
                list(~ log(.) - log(!!as.name(denom)) )))

In case there is a more complex situation than simple selecting one column eval with str2lang (or parse ) could be used.如果存在比简单选择一列更复杂的情况,可以使用str2lang (或parseeval In case it is an expression it could be used direct in eval如果它是一个表达式,它可以直接在eval

denom  <-  "z"
m %>% mutate(across(x:z, list(~ log(.) - log(eval(str2lang(denom))) )))
#  x  y  z       x_1        y_1 z_1
#1 1 11 21 -3.044522 -0.6466272   0
#2 2 12 22 -2.397895 -0.6061358   0
#3 3 13 23 -2.036882 -0.5705449   0
#4 4 14 24 -1.791759 -0.5389965   0
#5 5 15 25 -1.609438 -0.5108256   0

denom <- expression(z)
m %>% mutate(across(x:z, list(~ log(.) - log(eval(denom)) )))
#  x  y  z       x_1        y_1 z_1
#1 1 11 21 -3.044522 -0.6466272   0
#2 2 12 22 -2.397895 -0.6061358   0
#3 3 13 23 -2.036882 -0.5705449   0
#4 4 14 24 -1.791759 -0.5389965   0
#5 5 15 25 -1.609438 -0.5108256   0

m %>% mutate(across(x:z, list(~ log(.) - log(z) )))
#  x  y  z       x_1        y_1 z_1
#1 1 11 21 -3.044522 -0.6466272   0
#2 2 12 22 -2.397895 -0.6061358   0
#3 3 13 23 -2.036882 -0.5705449   0
#4 4 14 24 -1.791759 -0.5389965   0
#5 5 15 25 -1.609438 -0.5108256   0

More complex:更复杂:

denom <- "x + y"
m %>% mutate(across(x:z, list(~ log(.) - log(eval(str2lang(denom))) )))
#  x  y  z       x_1         y_1       z_1
#1 1 11 21 -2.484907 -0.08701138 0.5596158
#2 2 12 22 -1.945910 -0.15415068 0.4519851
#3 3 13 23 -1.673976 -0.20763936 0.3629055
#4 4 14 24 -1.504077 -0.25131443 0.2876821
#5 5 15 25 -1.386294 -0.28768207 0.2231436

denom <- expression(x + y)
m %>% mutate(across(x:z, list(~ log(.) - log(eval(denom)) )))
#  x  y  z       x_1         y_1       z_1
#1 1 11 21 -2.484907 -0.08701138 0.5596158
#2 2 12 22 -1.945910 -0.15415068 0.4519851
#3 3 13 23 -1.673976 -0.20763936 0.3629055
#4 4 14 24 -1.504077 -0.25131443 0.2876821
#5 5 15 25 -1.386294 -0.28768207 0.2231436

m %>% mutate(across(x:z, list(~ log(.) - log(x + y) )))
#  x  y  z       x_1         y_1       z_1
#1 1 11 21 -2.484907 -0.08701138 0.5596158
#2 2 12 22 -1.945910 -0.15415068 0.4519851
#3 3 13 23 -1.673976 -0.20763936 0.3629055
#4 4 14 24 -1.504077 -0.25131443 0.2876821
#5 5 15 25 -1.386294 -0.28768207 0.2231436

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM