我需要使用tidyverse中的函数在现有列的基础上创建新列.我计划使用across(),因为它允许动态重命名新变量,这在我的情况下越来越重要,并且节省了很多时间,尤其是当数据中有许多变量需要修改时.下面的函数无法按预期按列应用,它的行为很奇怪,通过更改P参数的值,我每次都得到了意外的输出,特别是当我将一些值设置为1时,就好像函数是按元素应用的,而不是按列应用的.

我想知道如何以更高效的方式编写这段代码来实现上述目标,我的意思是高效、更短、更快、更整洁.

Reprex

set.seed (123)
df <- tibble(id = 1:10,
               rosa = runif(10, min = 20.8, max = 36.5),
               lila = runif(10, min = 17, max = 37),
               blaue = runif(10, min = 23.3, max = 32.7))
df[c (2, 5, 8), c (2:4)] <- NA

Code

myfun <- function(x, P = 2, na.rm = FALSE){
    P ^ (min (x, na.rm = na.rm) - x)
}

P <- c(2, 1.5, 1.1) # fiddle with numbers here and see the output each time changes 
names <- c ("rosa", "lila", "blaue")
df %>%
    select(!!names) %>%
    mutate(across(.cols = !!names,
                  .fns = ~myfun(.x, P, na.rm = TRUE),
                  .names = "{.col}_P"))

Output

   + # A tibble: 10 × 6
    rosa  lila blaue    rosa_P     lila_P  blaue_P
   <dbl> <dbl> <dbl>     <dbl>      <dbl>    <dbl>
 1  25.3  36.1  31.7  0.0718    0.0000526  0.00793
 2  NA    NA    NA   NA        NA         NA      
 3  27.2  30.6  29.3  0.581     0.439      0.643  
 4  34.7  28.5  32.6  0.000110  0.0108     0.00401
 5  NA    NA    NA   NA        NA         NA      
 6  21.5  35.0  30.0  1         0.288      0.605  
 7  29.1  21.9  28.4  0.00524   1          0.0753 
 8  NA    NA    NA   NA        NA         NA      
 9  29.5  23.6  26.0  0.469     0.856      0.881  
10  28.0  36.1  24.7  0.0114    0.0000543  1      
Warning messages:
1: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length 
2: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length 
3: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length 

Expected Output

df %>%
select(!!names) %>%
mutate(rosa_P =  2^(min (rosa, na.rm = TRUE) - rosa)) %>%
mutate(lila_P =  1.5^(min (lila, na.rm = TRUE) - lila)) %>%
mutate(blaue_P = 1.1^(min (blaue, na.rm = TRUE) - blaue))

   + # A tibble: 10 × 6
    rosa  lila blaue    rosa_P   lila_P blaue_P
   <dbl> <dbl> <dbl>     <dbl>    <dbl>   <dbl>
 1  25.3  36.1  31.7  0.0718    0.00314   0.514
 2  NA    NA    NA   NA        NA        NA    
 3  27.2  30.6  29.3  0.0192    0.0302    0.643
 4  34.7  28.5  32.6  0.000110  0.0708    0.468
 5  NA    NA    NA   NA        NA        NA    
 6  21.5  35.0  30.0  1         0.00498   0.605
 7  29.1  21.9  28.4  0.00524   1         0.701
 8  NA    NA    NA   NA        NA        NA    
 9  29.5  23.6  26.0  0.00407   0.515     0.881
10  28.0  36.1  24.7  0.0114    0.00320   1    

推荐答案

你的问题是P向量,因为across不知道哪个数字属于什么调用,但会将所有三个数字传递给myfun.相反,你可以命名它,并使用cur_column().

使用all_of/any_of而不是!!可能更安全,并且使用names的向量的另一个名称比names更安全,因为它也是一个基函数.这可能会导致混淆.

library(dplyr)

P <- c(rosa = 2, lila = 1.5, blaue = 1.1)
colournames <- names(P) #c("rosa", "lila", "blaue")

df |>
  #select(all_of(colournames)) |>
  mutate(across(all_of(colournames),
                ~ P[cur_column()] ^ (min(., na.rm = TRUE) - .), # ~ my_fun(., P[cur_column()], na.rm = TRUE)
                .names = "{.col}_P"))

Output:

# A tibble: 10 × 6
    rosa  lila blaue    rosa_P   lila_P blaue_P
   <dbl> <dbl> <dbl>     <dbl>    <dbl>   <dbl>
 1  25.3  36.1  31.7  0.0718    0.00314   0.514
 2  NA    NA    NA   NA        NA        NA    
 3  27.2  30.6  29.3  0.0192    0.0302    0.643
 4  34.7  28.5  32.6  0.000110  0.0708    0.468
 5  NA    NA    NA   NA        NA        NA    
 6  21.5  35.0  30.0  1         0.00498   0.605
 7  29.1  21.9  28.4  0.00524   1         0.701
 8  NA    NA    NA   NA        NA        NA    
 9  29.5  23.6  26.0  0.00407   0.515     0.881
10  28.0  36.1  24.7  0.0114    0.00320   1    

Update, changed as OP example changed.

R相关问答推荐

NA仅省略具有NA的 Select 行

修改dDeliverr中列表列的最后一个元素

R -创建一列,指示另一列是否具有相同的值

在ComplexHeatmap中,如何更改anno_barplot()标题的Angular ?

使用ggplot 2根据R中的类别排列Likert比例gplot

如果列中存在相同的字符串,则对行值进行总和

随机森林回归:下拉列重要性

derrr mutate case_when grepl不能在R中正确返回值

用相同方法得到不同函数的ROC最优截断值

如何在emmeans中计算连续变量的对比度

如何在ggplot中标记qqplot上的点?

如何计算多个日期是否在一个日期范围内

更改STAT_VALLES/STAT_PEAKS中的箭头线宽/大小

以字符格式导入的ExcelElectron 表格日期列标题

根据约束随机填充向量的元素

如何使用同比折线图中的个别日

为什么我对圆周率图的蒙特卡罗估计是空的?

在点图上绘制置信度或预测区间ggplot2

错误包arrowR:READ_PARQUET/OPEN_DATASET&QOT;无法反序列化SARIFT:TProtocolException:超出大小限制&Quot;

随机将数据帧中特定列上的某些行设置为NA