【问题标题】:Return pmin or pmax of data.frame with multiple columns返回具有多列的 data.frame 的 pmin 或 pmax
【发布时间】:2014-10-09 00:15:41
【问题描述】:

有没有办法选择多列数据框的pmax/pmin??

我只想要返回的最大值或最小值,而不是整行。

max <- tail(df, n=1)
max
#                       v1     v2     v3     v4     v5     v6     v7     v8
#2014-10-03 17:35:00  58.91  45.81  33.06  70.76  36.39  45.53  33.52  34.36

pmax(max)
#                       v1     v2     v3     v4     v5     v6     v7     v8
#2014-10-03 17:35:00  58.91  45.81  33.06  70.76  36.39  45.53  33.52  34.36

对于这一行,我期望返回值:

70.76

...因为它是所有列的最大值。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    使用do.call 调用pmax 来比较每个行值的所有列,例如:

    dat <- data.frame(a=1:5,b=rep(3,5))
    
    #  a b
    #1 1 3
    #2 2 3
    #3 3 3
    #4 4 3
    #5 5 3
    
    do.call(pmax,dat)
    #[1] 3 3 3 4 5
    

    当您直接在整个 data.frame 上调用 pmax 时,它只有一个参数传递给函数,没有可比较的参数。因此,它只返回提供的参数,因为它必须是最大值。它适用于非数字和数字参数,即使它可能没有多大意义:

    pmax(7)
    #[1] 7
    
    pmax("a")
    #[1] "a"
    
    pmax(data.frame(1,2,3))
    #  X1 X2 X3
    #1  1  2  3
    

    do.call(pmax,...) 与data.frame 一起使用意味着您将data.frame 的每一列作为参数列表传递给pmax

    do.call(pmax,dat) 
    

    因此等价于:

    pmax(dat$a, dat$b)
    

    【讨论】:

    • 这不适用于 NA。如何将 na.rm = TRUE 传递给 do.call?
    • @JASC - do.call(pmax, c(dat, na.rm=TRUE))
    【解决方案2】:

    如果您愿意,可以使用dplyr 方式

    df <- structure(list(X = c("A", "B", "C", "D", "E", "F", "G", "H", 
                               "I", "J"), Y_1 = c(34, 29, 94, 53, 84, 53, 92, 41, 49, 32), Y_2 = c(43, 
                                                                                                   26, 29, 64, 68, 88, 36, 86, 74, 15), Y_3 = c(62, 72, 69, 54, 
                                                                                                                                                80, 49, 51, 41, 46, 68), Y_4 = c(92, 45, 21, 27, 60, 32, 40, 
                                                                                                                                                                                 40, 39, 89), Y_5 = c(28, 79, 34, 84, 58, 16, 69, 53, 78, 80), 
                         Y_6 = c(91, 55, 45, 70, 81, 19, 33, 90, 28, 82), Y_7 = c(95, 
                                                                                  75, 11, 81, 12, 38, 53, 88, 74, 51), Y_8 = c(69, 99, 44, 
                                                                                                                               20, 53, 57, 79, 45, 21, 47), Y_9 = c(67, 44, 88, 75, 76, 
                                                                                                                                                                    70, 18, 80, 32, 83), Y_10 = c(16, 80, 41, 47, 72, 47, 89, 
                                                                                                                                                                                                  96, 23, 64)), row.names = c(NA, -10L), class = c("tbl_df", 
                                                                                                                                                                                                                                                   "tbl", "data.frame"))
    df
    #> # A tibble: 10 x 11
    #>    X       Y_1   Y_2   Y_3   Y_4   Y_5   Y_6   Y_7   Y_8   Y_9  Y_10
    #>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #>  1 A        34    43    62    92    28    91    95    69    67    16
    #>  2 B        29    26    72    45    79    55    75    99    44    80
    #>  3 C        94    29    69    21    34    45    11    44    88    41
    #>  4 D        53    64    54    27    84    70    81    20    75    47
    #>  5 E        84    68    80    60    58    81    12    53    76    72
    #>  6 F        53    88    49    32    16    19    38    57    70    47
    #>  7 G        92    36    51    40    69    33    53    79    18    89
    #>  8 H        41    86    41    40    53    90    88    45    80    96
    #>  9 I        49    74    46    39    78    28    74    21    32    23
    #> 10 J        32    15    68    89    80    82    51    47    83    64
    
    library(dplyr)
    
    df %>% rowwise() %>%
      mutate(max_val = max(c_across(where(is.numeric))))
    #> # A tibble: 10 x 12
    #> # Rowwise: 
    #>    X       Y_1   Y_2   Y_3   Y_4   Y_5   Y_6   Y_7   Y_8   Y_9  Y_10 max_val
    #>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>
    #>  1 A        34    43    62    92    28    91    95    69    67    16      95
    #>  2 B        29    26    72    45    79    55    75    99    44    80      99
    #>  3 C        94    29    69    21    34    45    11    44    88    41      94
    #>  4 D        53    64    54    27    84    70    81    20    75    47      84
    #>  5 E        84    68    80    60    58    81    12    53    76    72      84
    #>  6 F        53    88    49    32    16    19    38    57    70    47      88
    #>  7 G        92    36    51    40    69    33    53    79    18    89      92
    #>  8 H        41    86    41    40    53    90    88    45    80    96      96
    #>  9 I        49    74    46    39    78    28    74    21    32    23      78
    #> 10 J        32    15    68    89    80    82    51    47    83    64      89
    

    reprex package (v2.0.0) 于 2021-05-08 创建

    【讨论】:

      【解决方案3】:

      感谢 AnilGovyl 提供数据!

      这是另一个dplyr 选项,使用rlang 和准引用:在这里学习:dplyr mutate rowwise max of range of columns Ben 的回答

      首先我们要测试所有列,然后我们可以使用 !!!rlang::syms 计算这些列的每一行的并行最大值:

      rlang::syms 接受字符串输入(列名),并将其转换为符号 !!! 取消引用并拼接它的参数,这里是列名。

      library(dplyr)
      library(rlang)
      
      df_cols <- df %>% select(where(is.numeric)) %>% names()
      
      df %>% 
      mutate(max_val=pmax(!!!rlang::syms(df_cols)))
      

      输出:

         X       Y_1   Y_2   Y_3   Y_4   Y_5   Y_6   Y_7   Y_8   Y_9  Y_10 max_val
         <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>
       1 A        34    43    62    92    28    91    95    69    67    16      95
       2 B        29    26    72    45    79    55    75    99    44    80      99
       3 C        94    29    69    21    34    45    11    44    88    41      94
       4 D        53    64    54    27    84    70    81    20    75    47      84
       5 E        84    68    80    60    58    81    12    53    76    72      84
       6 F        53    88    49    32    16    19    38    57    70    47      88
       7 G        92    36    51    40    69    33    53    79    18    89      92
       8 H        41    86    41    40    53    90    88    45    80    96      96
       9 I        49    74    46    39    78    28    74    21    32    23      78
      10 J        32    15    68    89    80    82    51    47    83    64      89
      

      【讨论】:

      • 您也可以使用max.col 获取colnames,其中最大值为
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2013-12-20
      • 2021-12-27
      • 2011-12-24
      • 2022-11-24
      • 1970-01-01
      相关资源
      最近更新 更多