代码之家  ›  专栏  ›  技术社区  ›  Omry Atia

dpylr在每一列分别使用几个参数的自定义函数进行变异

  •  2
  • Omry Atia  · 技术社区  · 6 年前

    我有以下要应用于数据帧列的函数:

    ff <- function(w, epsi, df) {
      res <- w*(max(df, na.rm = T) - min(df, na.rm=T)+2*epsi)+min(df, na.rm = T) - epsi
      return(res)
    }
    

    该函数应应用于 w ,使用参数 epsi df . 函数必须取 W 并乘以相应列的最大值 东风 减去该列的最小值 东风 等等。

    例如:

    > w
    # A tibble: 5 x 2
        A       B
      <dbl>   <dbl>
    1 0.290  0.928  
    2 0.917  0.929  
    3 0.910  0.919  
    4 0.243  0.908  
    5 0.936  0.901  
    

    东风 是:

    > df
    # A tibble: 10 x 2
       A     B
      <dbl> <dbl>
    1 0.977 1.03 
    2 1.04  1.15 
    3 0.929 0.875
    4 1.12  1.15 
    5 0.913 1.05 
    6 1.00  1.09 
    7 0.972 1.03 
    8 0.919 1.04 
    9 0.935 0.973
    10 1.08  1.17 
    

    所以对于第一个元素 W ,0.290,函数将0.290乘以 东风 编队 A (1.12)等等。

    如何使用 dplyr W ?

    我试过:

    w_new = w %>%  mutate_each(ff(w,0.001, df))
    

    但它不是一次只接受一个列,而是试图同时对所有列进行操作。

    2 回复  |  直到 6 年前
        1
  •  2
  •   MKR    6 年前

    OP表示希望使用 dplyr 基于此问题的解决方案,因此我想使用 DPLYR .

    在需要在另一个表中查找相应列(名称)的情况下,最好不要依赖列的顺序,而应使用特定的列名称。这个 quo_name quo 函数提供对范围内的列名的访问 dplyr::mutate_all 功能。

    使用的解决方案 全部变异 可以是:

    # Re-wirte fucntion to accept the column name for df
    ff <- function(x, epsi, colName) {
      res <- x*(max(df[,colName], na.rm = TRUE) - min(df[,colName], na.rm=TRUE) +
             2*epsi)+min(df[,colName], na.rm = TRUE) - epsi
      return(res)
    }
    
    library(dplyr)
    
    # The corresponding column names is passed to ff using quo_name(quo(.))
    w %>% mutate_all(funs(ff(., 0.001, quo_name(quo(.)) )))
    #          A        B
    # 1 0.972610 1.149616
    # 2 1.103653 1.149913
    # 3 1.102190 1.146943
    # 4 0.962787 1.143676
    # 5 1.107624 1.141597
    

    数据:

    w <- read.table(text = 
    "A       B
    1 0.290  0.928  
    2 0.917  0.929  
    3 0.910  0.919  
    4 0.243  0.908  
    5 0.936  0.901",
    header = TRUE)
    
    
    df <- read.table(text = 
    "A     B
    1 0.977 1.03 
    2 1.04  1.15 
    3 0.929 0.875
    4 1.12  1.15 
    5 0.913 1.05 
    6 1.00  1.09 
    7 0.972 1.03 
    8 0.919 1.04 
    9 0.935 0.973
    10 1.08  1.17",
    header = TRUE)
    
        2
  •  1
  •   Maurits Evers    6 年前

    下面是使用 mapply的base r解决方案

    mapply(
    函数(x,y,epsi=0.001)
    x*(max(y,na.rm=t)-min(y,na.rm=t)+2*epsi)+min(y,na.rm=t)-epsi,
    W,DF)
    #A B
    #[1,]0.972610 1.149616
    #[2,]1.103653 1.149913
    #[3,]1.102190 1.146943
    #[4,]0.962787 1.143676
    #[5,]1.107624 1.141597
    < /代码> 
    
    

    说明:mapply将函数应用于w和dfcolumn by column,并将结果简化为5x2matrix。

    重新定义ff稍微,这可以更简洁地写为

    ff<-函数(x,y,epsi=0.001)
    x*(最大值(y,na.rm=t)-最小值(y,na.rm=t)+2*epsi)+最小值(y,na.rm=t)-epsi
    映射(FF、W、DF)
    < /代码> 
    
    

    或使用purr::map2_dfas

    w%>%map2_df(df,ff)
    ##A台架:5 x 2
    αA
    #<dbl><dbl>
    α1 0.973 0.973
    α2 1.10 1.10
    α3 1.10 1.10
    α4 0.963 0.963
    α5 1.11 1.11
    < /代码> 
    
    
    < H2>更新< /H2>

    从一个非常快速和肮脏的micronchmarkanalysis of themutate-allandmap2approaches look like this:。

    res<-微基准(
    MAP2= {
    FF<-功能(x,y,epsi=0.001)
    x*(最大值(y,na.rm=t)-最小值(y,na.rm=t)+2*epsi)+最小值(y,na.rm=t)-epsi
    w%>%map2_df(df,ff)
    }
    突变基因ALL={
    FF<-函数(x,epsi,colname){
    res<-x*(最大值(df[,colname],na.rm=true)-最小值(df[,colname],na.rm=true)+
    2*epsi)+min(df[,colname],na.rm=true)-epsi
    返回(RES)
    }
    w%>%突变所有(funs(ff(,0.001,quo名称(quo(.)))
    }
    )
    物件
    #单位:微秒
    #expr min lq平均中位数uq max neval
    #地图2 320.537 371.1365 495.7786 397.6755 449.4445 8599.661 100
    #突变所有1916.788 1998.2105 2312.5878 2059.7650 2290.1415 11169.320 100
    
    图书馆(ggplot2)
    自动绘图(RES)
    < /代码> 
    
    

    说明:默普将函数应用于wdf并将结果简化为5x2matrix.

    重新定义ff稍微说一下,这可以更简洁地写为

    ff <- function(x, y, epsi = 0.001)
        x * (max(y, na.rm = T) - min(y, na.rm = T) + 2 * epsi) + min(y, na.rm = T) - epsi
    mapply(ff, w, df)
    

    或使用purrr::map2_df作为

    w %>% map2_df(df, ff)
    ## A tibble: 5 x 2
    #      A     B
    #  <dbl> <dbl>
    #1 0.973  1.15
    #2 1.10   1.15
    #3 1.10   1.15
    #4 0.963  1.14
    #5 1.11   1.14
    

    更新

    非常快速和肮脏的结果microbenchmark分析mutate_allmap2方法如下:

    res <- microbenchmark(
        map2 = {
            ff <- function(x, y, epsi = 0.001)
                x * (max(y, na.rm = T) - min(y, na.rm = T) + 2 * epsi) + min(y, na.rm = T) - epsi
            w %>% map2_df(df, ff)
        },
        mutate_all = {
            ff <- function(x, epsi, colName) {
                res <- x*(max(df[,colName], na.rm = TRUE) - min(df[,colName], na.rm=TRUE) +
             2*epsi)+min(df[,colName], na.rm = TRUE) - epsi
                return(res)
            }
            w %>% mutate_all(funs(ff(., 0.001, quo_name(quo(.)) )))
        }
    )
    res
    #Unit: microseconds
    #       expr      min        lq      mean    median        uq       max neval
    #       map2  320.537  371.1365  495.7786  397.6755  449.4445  8599.661   100
    # mutate_all 1916.788 1998.2105 2312.5878 2059.7650 2290.1415 11169.320   100
    
    library(ggplot2)
    autoplot(res)
    

    enter image description here