【问题标题】:Creating a function with multiple arguments using dplyr使用 dplyr 创建具有多个参数的函数
【发布时间】:2016-11-23 07:24:39
【问题描述】:

我正在努力在自己的函数中使用dplyrfunctions。我更接近理解,但仍然没有完全理解。 这里我有 df 包含 typeD10 变量。

df <- data.frame(type = c("KL", "KL", "A", "A", "B", "B", "9999", "-1"), 
                 D10 = rnorm(8, 3, 4))

我想写一个函数,如果type == "KL"; 则在新列中返回M"-1" 如果是 type %in% c(9999, -1) 并且对于所有其他情况将返回 K。我希望9999, -1, KL 的值在函数启动时可以更改。

我的尝试以如下所示的功能结束:

klme <- function(dat, met, minusy = c(-1, 9999), Sortnr, type){
  mutate_call <- lazyeval::interp(~ifelse(a %in% met, "M", ifelse(a %in% minusy, "-1", "K")), a = as.name(Sortnr))
  dat %>% mutate_(.dots = setNames(list(mutate_call), type))
}

klme(df, c("KL"), minusy = c(-1, 9999), "Sortnr", "typ")

typ 列中只返回K,而我想获得这样的输出:

  type        D10 type.1
1   KL -5.3210620      M
2   KL  4.4832414      M
3    A -5.3979886      K
4    A  2.7933964      K
5    B -0.9602293      K
6    B  4.5097305      K
7 9999 -3.9650796     -1
8   -1  5.2700609     -1

【问题讨论】:

  • 链接不起作用,无论如何我想我读了它并完成了我提出的功能
  • 你必须将Sortnr = "type" 传递给你的函数,否则你的结果将永远是K
  • 为什么不只使用df$type.1 &lt;- c('K','-1','M')[1 + (df$type %in% c('9999','-1')) + 2*(df$type == 'KL')] 或嵌套ifelse:df$type.1 &lt;- ifelse(df$type %in% c('9999','-1'), '-1', ifelse(df$type == 'KL', 'M', 'K'))
  • 我想要一个函数,我可以将值 KLM K 更改为 ex ST 等。我不想复制所有链并在新地方更改

标签: r dplyr nse


【解决方案1】:

我相信您正在寻找这个,请记住您需要 interp 所有可变的值(@wici 也是正确的,您对 klme 的调用不应该有 Sortnr,因为这不是df):

df <- data.frame(type = c("KL", "KL", "A", "A", "B", "B", "9999", "-1"), 
                 D10 = rnorm(8, 3, 4))

klme <- function(dat, met, minusy = c(-1, 9999), Sortnr, type){
  mutate_call <- lazyeval::interp(~ifelse(a %in% y, "M", 
                                          ifelse(a %in% z, "-1", "K")),
                                  a = as.name(Sortnr),
                                  y = met,
                                  z = minusy)
  dat %>% mutate_(.dots = setNames(list(mutate_call), type))
}

klme(df, c("KL"), minusy = c('-1', '9999'), "type", "typ")
  type        D10 typ
1   KL  6.4760905   M
2   KL  7.5196368   M
3    A  2.2588101   K
4    A  1.4910878   K
5    B -0.3357310   K
6    B  1.9693856   K
7 9999 -0.3820483  -1
8   -1  4.5595150  -1

【讨论】:

    【解决方案2】:

    您可以从 purrr映射如下:

    library(dplyr)
    library(purrr)
    

    定义一个函数来检查你的条件:

    GetType <- function(x)
    {
          if(x=="KL")  "M"
            else if(x %in% c(9999,-1) ) "-1"
            else "K"
    }
    

    然后使用 map 如下,它从每一行获取类型,将其传递给 GetType 函数并返回新列中的值:

    df <- df %>% 
            mutate(type.1=map_chr(type,GetType))
    
    > df
      type        D10 type.1
    1   KL  3.0820944      M
    2   KL  8.0126703      M
    3    A  8.0629672      K
    4    A  5.8460856      K
    5    B  0.6803590      K
    6    B -1.1148491      K
    7 9999 -0.4981576     -1
    8   -1  1.0648742     -1
    

    编辑 原则上,您还可以将要比较的值传递给函数:

    val <- list("KL",c(9999,1))
    
    GetType <- function(x,y)
    
    {
             if(x==y[[1]])  "M"
            else if(x %in% y[[2]] ) "-1"
            else "K"
    }
    
    
    > GetType(df$type[1],val)
    [1] "M"
    

    【讨论】:

    • 这不是我想要的,我不想在运行时在函数内部进行更改。我宁愿让函数参数可以改变
    • 啊哈,原则上你可以像在编辑的解决方案中一样传递你想要的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2017-06-17
    相关资源
    最近更新 更多