【问题标题】:R function with argument as part of new variable带有参数的R函数作为新变量的一部分
【发布时间】:2018-09-14 09:58:42
【问题描述】:

我想创建一个函数来将两列相加,其中一个单词连接两列并且有三个集合。我想将该词作为唯一参数传递,并添加一个具有相同名称的新列。像这样。

the_first_x <- c(0,0,10,0)
the_second_x <- c(10,0,10,0)
the_first_y <- c(0,5,5,5)
the_second_y <- c(5,5,0,0)

df <- data.frame(the_first_x,
                 the_second_x,
                 the_first_y,
                 the_second_y)

summing <- function(letter){
  df$letter <- the_first_letter + the_second_letter
}

这样使用以下命令会添加一个以该字母作为名称并将总和作为其行的列

summing(x)
summing(y)

通过这样做,letter 参数无法识别,而使用 paste() 之类的东西会使该参数被括号括起来,也无法识别。

【问题讨论】:

    标签: r function


    【解决方案1】:

    这是一个更好的方法。 (应尽可能避免使用&lt;&lt;-

    summing <- function(data, letter, pattern = paste0(letter,"$")){
        data[[letter]] <- rowSums(data[,grepl(pattern,names(data),)], na.rm = T)
        return(data)
    }
    

    这个函数在使用管道时特别方便:

    library(magrittr)
    df %>% summing("x") %>% summing("y")
    
    #  the_first_x the_second_x the_first_y the_second_y  x  y
    #1           0           10           0            5 10  5
    #2           0            0           5            5  0 10
    #3          10           10           5            0 20  5
    #4           0            0           5            0  0  5
    

    当然,你可以不用管道来使用它:

    ans <- summing(df, "x")
    summing(ans, "y")
    

    pattern 参数采用正则表达式。这样一来,您要添加的列就非常笼统和具体了。

    【讨论】:

    • 谢谢,这行得通!它也可以在没有模式的情况下工作:summing &lt;- function(data, letter){ data[[letter]] &lt;- rowSums(data[,grepl(letter,names(data),)], na.rm = T) return(data) }
    • 确保在这个例子中确实如此。但是考虑一个列名xbox。当您键入 "x" 时,您也会匹配它,因此也将其相加。正则表达式模式确保您只匹配您打算添加的列。在模式中尽可能具体。
    【解决方案2】:

    我建议不要使用 (1) &lt;&lt;- 和 (2) deparse(substitute(...))。 关于 (1),这是从 What is the difference between assign() and <<- in R? 获取的关于什么 使用 &lt;&lt;- 的建议(括号中的添加是我的):

    [&lt;&lt;-] 的邪恶和错误用法是修改全局环境中的变量。

    这是一个使用 rlang 语法的 tidyverse 选项:

    library(tidyverse)
    my_sum <- function(df, x) {
        x <- enquo(x)
        col <- names(df)[str_detect(names(df), quo_name(x))]
        df %>% mutate(!!x := !!sym(col[1]) + !!sym(col[2]))
    }
    df %>% my_sum(x)
    #  the_first_x the_second_x the_first_y the_second_y  x
    #1           0           10           0            5 10
    #2           0            0           5            5  0
    #3          10           10           5            0 20
    #4           0            0           5            0  0
    
    df %>% my_sum(y)
    #  the_first_x the_second_x the_first_y the_second_y  y
    #1           0           10           0            5  5
    #2           0            0           5            5 10
    #3          10           10           5            0  5
    #4           0            0           5            0  5
    

    我们可以很好地链接多个my_sum 调用:

    df %>% my_sum(x) %>% my_sum(y)
    #  the_first_x the_second_x the_first_y the_second_y  x  y
    #1           0           10           0            5 10  5
    #2           0            0           5            5  0 10
    #3          10           10           5            0 20  5
    #4           0            0           5            0  0  5
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 2023-03-24
    • 2015-03-14
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2018-08-01
    相关资源
    最近更新 更多