【问题标题】:Min and Median of Multiple Columns of a DF by Row in RR中按行排列的DF的多列的最小值和中值
【发布时间】:2016-03-09 21:20:18
【问题描述】:

假设dataframe 看起来像:

V1  V2  V3
5   8   12
4   9   5
7   3   9
...

如何将列添加到dataframe 以获取这 3 列的最小值和中值,为每一行计算?

生成的 DF 应如下所示:

V1  V2  V3  Min  Median
5   8   12  5    8
4   9   5   4    5
7   3   9   3    7
...

我尝试使用dplyr::mutate

mutate(df, Min = min(V1,V2,V3)) 

但这需要整个数据帧的最小值并将该值放在每一行中。如何获取每行的最小值和中位数?

对于 Mean,我可以在 mutate 中使用 rowMeans,但是对于 min 和 median 没有类似的函数。

也试过了,

lapply(df[1:3], median)

但它只是产生每列的中位数

dd <- read.table(header = TRUE, text = 'V1  V2  V3
5   8   12
4   9   5
7   3   9')

【问题讨论】:

标签: r


【解决方案1】:

使用dplyr,使用函数rowwise

library(dplyr)
mutate(rowwise(df), min = min(V1, V2, V3), median = median(c(V1, V2, V3)))
# Using the pipe operator %>%
df %>% 
  rowwise() %>% 
  mutate(min= min(V1, V2, V3), median = median(c(V1, V2, V3)))

输出:

Source: local data frame [3 x 5]
Groups: <by row>

     V1    V2    V3   min median
  (int) (int) (int) (int)  (int)
1     5     8    12     5      8
2     4     9     5     4      5
3     7     3     9     3      7

【讨论】:

    【解决方案2】:

    您可以像这样使用apply(1表示按行计算,2表示按列计算):

    the_min <- apply(df, 1, min)   
    the_median <- apply(df, 1, median)
    df$Min <- the_min
    df$Median <- the_median
    

    【讨论】:

    • 我认为它在计算中位数时不起作用,因为您也在使用“Min”列
    • 没错,所以你应该先单独计算。我会编辑。
    • 你真的不需要先保存到单独的变量中;你可以直接上专栏:df$Min &lt;- apply(df, 1, min); df$Median &lt;- apply(df[,1:3], 1, median)
    【解决方案3】:
    min<-apply(df,1,min)
    median<-apply(df,1,median)
    df$Min<-min
    df$Median<-median
    

    【讨论】:

      【解决方案4】:

      您可以使用dplyr 来完成此操作,但您需要按唯一的 ID 变量进行分组,以便为​​每一行单独评估。如果说,V1 绝对是独一无二的,这很容易:

      dat %>% group_by(V1) %>% mutate(min = min(V1, V2, V3), median = median(c(V1, V2, V3)))
      

      如果您没有唯一 ID,您可以很容易地创建(并删除,如果您愿意)一个:

      dat %>% mutate(id = seq_len(n())) %>% group_by(id) %>% 
        mutate(min = min(V1, V2, V3), median = median(c(V1, V2, V3))) %>% 
        ungroup() %>% select(-id)
      

      无论哪种方式,你都会得到

      Source: local data frame [3 x 5]
      
           V1    V2    V3   min median
        (int) (int) (int) (int)  (int)
      1     5     8    12     5      8
      2     4     9     5     4      5
      3     7     3     9     3      7
      

      【讨论】:

      • dplyr 还有一个rowwise 函数,比如dat %&gt;% mutate(min = pmin(V1,V2,V3)) %&gt;% rowwise() %&gt;% mutate(med = median(c(V1,V2,V3)))
      • @Frank Cool,这很有用!我知道那里有很多用于处理行的函数,但我没有用过那么多。
      • 为什么你将c(V1.V2,V3) 用于combine col 名称作为中位数而不是min
      • @ok1more 抱歉,迟到了。但是因为min()的第一个参数是...,而median()x,所以在后者中,元素必须被收集到一个向量中,而min(3, 1, 2)min(c(3, 1, 2))都返回相同的东西,所以没关系。
      【解决方案5】:
      data<- data.frame(a=1:3,b=4:6,c=7:9)
      data
      #   a b c
      # 1 1 4 7
      # 2 2 5 8
      # 3 3 6 9
      
      data$Min <- apply(data,1,min)
      data
      #   a b c Min
      # 1 1 4 7   1
      # 2 2 5 8   2
      # 3 3 6 9   3
      
      data$Median <-apply(data[,1:3],1,median)
      data
      #     a b c min median
      #  1  1 4 7   1    4
      #  2  2 5 8   2    5
      #  3  3 6 9   3    6
      

      希望这会有所帮助。

      【讨论】:

      • @Frank 是的。你说的对。让我纠正一下。谢谢。
      • @Frank 完成更正。现在中位数不包括“Min”列。
      猜你喜欢
      • 2019-10-14
      • 1970-01-01
      • 2015-12-14
      • 2020-10-08
      • 1970-01-01
      • 2015-07-02
      • 2015-06-18
      • 1970-01-01
      • 2019-07-23
      相关资源
      最近更新 更多