R:来自> 2列的data.frame行的聚合(中值)

时间:2016-05-03 07:23:18

标签: r

我想汇总我的data.frame。

以下是示例数据:

data <- structure(list(Charge = c(210133L, 210133L, 210133L, 210152L, 
                                  210152L, 210152L, 210152L, 210180L, 210180L, 210180L), Seq = c(1L, 
                                                                                                       2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 2L), x = c(NA, 1.5, 2, 
                                                                                                                                                         1.5, 1, 0.67, 1.17, 1, 1, 1), y = c(0.5, 0.5, 1, NA, 0.5, 
                                                                                                                                                                                                    0.5, 0.5, 0.5, 0.5, 0.5)), .Names = c("Charge", "Seq", 
                                                                                                                                                                                                                                          "x", "y"), row.names = c(NA, 10L), class = "data.frame")

*用于解释(与上述数据相同,格式不同):

   Charge Seq    x   y
1  210133   1   NA 0.5
2  210133   2 1.50 0.5
3  210133   3 2.00 1.0
4  210152   1 1.50  NA
5  210152   2 1.00 0.5
6  210152   3 0.67 0.5
7  210152   4 1.17 0.5
8  210180   1 1.00 0.5
9  210180   2 1.00 0.5
10 210180   2 1.00 0.5

对于每个唯一的费用,必须为Seq&gt; 1执行x和y列行的中位数。

因此,例如对于此示例数据,我想获得带有x和y行中间值的附加行,用于seq&gt; 1:

       Charge Seq    x   y
    1  210133   1   NA 0.5
    2  210133   2 1.50 0.5
    3  210133   3 2.00 1.0
    4  210133   >1 1.75 0.75 #here is additional row with median of x and y
    4  210152   1 1.50  NA
    5  210152   2 1.00 0.5...

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

我们可以使用data.table。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(data)),按&#34; Charge&#34;分组,循环显示列(lapply(.SD,...),根据median中的.SDcols获取Seq >1列在&#39; i&#39; (list),创建一个&#39; Seq&#39;值为&#34;&gt; 1&#34;的列。将原始数据与新内容一起放在rbind中,使用order合并数据集,并在必要时library(data.table) setDT(data) res <- data[Seq > 1L, lapply(.SD, median, na.rm=TRUE), by = Charge, .SDcols = x:y][, Seq := ">1"][] ans <- setorder(rbind(data, res), Charge, Seq) # Charge Seq x y # 1: 210133 1 NA 0.50 # 2: 210133 2 1.50 0.50 # 3: 210133 3 2.00 1.00 # 4: 210133 >1 1.75 0.75 # 5: 210152 1 1.50 NA # 6: 210152 2 1.00 0.50 # 7: 210152 3 0.67 0.50 # 8: 210152 4 1.17 0.50 # 9: 210152 >1 1.00 0.50 #10: 210180 1 1.00 0.50 #11: 210180 2 1.00 0.50 #12: 210180 2 1.00 0.50 #13: 210180 >1 1.00 0.50

dplyr

使用class的类似选项,我们转换了character&#34; Seq&#34;到原始数据集中的filter。然后,median为&#34; Seq&#34;不等于1,按&#34; Charge&#34;分组,我们得到summarise_each列的bind_rows,在输出中创建一个新列&#34; Seq&#34;,然后使用order将原始数据与新数据绑定,并在必要时绑定library(magrittr) library(dplyr) data %<>% mutate(Seq = as.character(Seq)) data %>% filter(Seq!="1") %>% group_by(Charge) %>% summarise_each(funs(median=median(., na.rm=TRUE)), x:y) %>% mutate(Seq = ">1") %>% bind_rows(data, .) %>% mutate(Seq = factor(Seq, levels = c(unique(data$Seq), ">1"))) %>% arrange(Charge, Seq)

Ti.Media.AudioPlayer

答案 1 :(得分:2)

使用data.table执行相同操作的另一种方法:

library(data.table)

setDT(data)

test <- function(x){
    seq.gt.1 <- which(x$Seq > 1)

    median.1 <- median(x$x[seq.gt.1],na.rm=T)
    median.2 <- median(x$y[seq.gt.1],na.rm=T)

    return (rbind(x,data.table(Seq='>1',x=median.1,y=median.2)))
}

data[,test(.SD),by=Charge]

 ##   Charge Seq    x    y
 ##1: 210133   1   NA 0.50
 ##2: 210133   2 1.50 0.50
 ##3: 210133   3 2.00 1.00
 ##4: 210133  >1 1.75 0.75
 ##5: 210152   1 1.50   NA
 ##6: 210152   2 1.00 0.50
 ##7: 210152   3 0.67 0.50
 ##8: 210152   4 1.17 0.50
 ##9: 210152  >1 1.00 0.50
##10: 210180   1 1.00 0.50
##11: 210180   2 1.00 0.50
##12: 210180   2 1.00 0.50
##13: 210180  >1 1.00 0.50