【问题标题】:Pass data frame and reference it for assignment inside function in R传递数据框并引用它以在 R 中的函数内部分配
【发布时间】:2022-01-23 18:38:28
【问题描述】:

在通过函数传递数据框后,我在分配时被绊倒了。 实际功能要大得多,但下面是一个示例。 目标:如果季度列名称在 active_quarters 向量中,则什么也不做。如果不是,则为数据框该列中的所有值分配空白。

我知道它试图明确引用“some_data_frame”,但我是在空白,双关语,关于如何在给定循环迭代的情况下正确分配空白。

代码:

library(dplyr)
active_quarters <- c("Q1", "Q2")

data_frame_dummy <- data.frame("Q1" = c(1:4),
                               "Q2" = c(5:8),
                               "Q3" = c(9:12),
                               "Q4" = c(13:16))

create_blanks<- function(quarters_list,some_data_frame){

  for(qcols in c("Q1", "Q2", "Q3", "Q4")){
    if(qcols %in% quarters_list){
      next
    }else{
      some_data_frame[,qcols] <<- ""
      
    }
  } # End of quarter if/else
} # End of function

create_blanks(active_quarters, data_frame_dummy)

结果:

> create_blanks(active_quarters, data_frame_dummy)
Error in some_data_frame[, qcols] <<- "" : 
  object 'some_data_frame' not found

想要的结果:

> data_frame_dummy
  Q1 Q2 Q3 Q4
1  1  5      
2  2  6      
3  3  7      
4  4  8   

【问题讨论】:

    标签: r dataframe function dplyr variable-assignment


    【解决方案1】:

    除非绝对必要,否则尽量不要使用&lt;&lt;-。函数不应更改现有对象。所以只需让函数返回some_data_frame,然后根据需要显式分配它。

    create_blanks<- function(quarters_list,some_data_frame){
      
      for(qcols in c("Q1", "Q2", "Q3", "Q4")){
        if(qcols %in% quarters_list){
          next
        }else{
          some_data_frame[,qcols] <- ""
          
        }
      } # End of quarter if/else
      some_data_frame
    } # End of function
    data_frame_dummy <- create_blanks(active_quarters, data_frame_dummy)
    data_frame_dummy
       Q1 Q2 Q3 Q4
    1  1  5      
    2  2  6      
    3  3  7      
    4  4  8      
    

    【讨论】:

    • 谢谢。我明白你在说什么。我正在使用双重分配来查找错误。但我认为这会奏效。我没有考虑将其重新分配给数据框的名称。谢谢!
    【解决方案2】:

    这对你有用吗?如果要将 0 分配给不在 .col 参数中的列,则可以否定选择

    library(tidyverse)
    
    active_quarters <- c("Q1", "Q2")
    
    data_frame_dummy <- data.frame("Q1" = c(1:4),
                                   "Q2" = c(5:8),
                                   "Q3" = c(9:12),
                                   "Q4" = c(13:16))
    
    
    data_frame_dummy |> 
      mutate(across(!active_quarters,.fns = ~ 0))
    #> Note: Using an external vector in selections is ambiguous.
    #> i Use `all_of(active_quarters)` instead of `active_quarters` to silence this message.
    #> i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
    #> This message is displayed once per session.
    #>   Q1 Q2 Q3 Q4
    #> 1  1  5  0  0
    #> 2  2  6  0  0
    #> 3  3  7  0  0
    #> 4  4  8  0  0
    

    reprex package (v2.0.1) 于 2022-01-23 创建

    【讨论】:

    • 您也可以按照 dplyr 的建议使用 all_of 来完善选择
    • 不是我想要的,但这实际上可以帮助我解决其他一些问题,所以谢谢!
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2016-02-09
    • 2021-08-21
    • 1970-01-01
    • 2020-10-03
    相关资源
    最近更新 更多