我想汇总我的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...
感谢您的帮助!
答案 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