我有一个包含3列的data.frame,每个列都可以被认为是一个因素。我想在data.frame上计算一些统计数据并将其存储在一个新的框架中。更具体地说,我有以下字段:
obs, len, src
A 10 X
B 10 Y
我想计算每个长度的每个来源的细分(即来自X的长度为10的观察的百分比是“A”,“B”等)。
一个明显的方法是使用两个for循环迭代长度和源,然后使用nrow()和count()来获取我需要计算的值,如下所示:
relevant_subset <- data[data$src==source & data$len==length,]
breakdown_info <- count(relevant_subset)
breakdown_info$frac <- breakdown_info$freq / nrow(relevant_subset)
有没有办法避免使用double for循环并使用更加向量化的方法?是否有一种智能的方法来预先分配新帧,该帧将保存每个长度和源的修改后的breakdown_info?
答案 0 :(得分:2)
aggregate
是您完成这些任务的朋友:
示例数据:
set.seed(23)
test <- data.frame(
obs=sample(LETTERS[1:2],20,replace=TRUE),
len=sample(c(10,20),20,replace=TRUE),
src=sample(LETTERS[24:25],20,replace=TRUE)
)
汇总:
aggregate(obs ~ src + len,data=test, function(x) prop.table(table(x)))
src len obs.A obs.B
1 X 10 0.6000000 0.4000000
2 Y 10 0.2000000 0.8000000
3 X 20 0.2500000 0.7500000
4 Y 20 0.1666667 0.8333333
答案 1 :(得分:1)
这是plyr
包的制作!
格式为<input_type><output_type>ply
。例如,如果输入为data.frame
,并且您希望输出为data.frame
,请使用ddply
。
要使用它,请指定输入data.frame
,要分组的列,然后指定从每个组构造data.frame
的函数。添加了分组列的结果data.frames
将组合到输出data.frame
中。
在类似于你的例子的情况下,你可以做到
require(plyr)
a <- data.frame(
obs=factor(c('A','A','A','B','B')),
len=c(10,10,10,10,210),
src=factor(c('X','X','Y','Y','Z')))
然后
z <- ddply(
a,
.(obs),
function(df){
data.frame(mean.len=mean(df$len))
})
会产生
data.frame(
obs=c('A', 'B'),
mean.length(10, 110))
,而
ddply(a, .(src), function(df){
data.frame(
num.obs.A = sum(df$obs == 'A'),
num.obs.B = sum(df$obs == 'B'))})
会产生
data.frame(
src=c('X','Y', 'Z'),
num.obs.A = c(3,1,0),
num.obs.B = c(0,1,1))
网站http://plyr.had.co.nz/也有很好的文档。
答案 2 :(得分:0)
您还没有说明您希望将data.frame作为输出的原因。对你来说也许是最好的,也许不是。你也不清楚什么比例是什么,但我认为以下可能最好地解决你的问题。
prop.table( table(test) )
您可以略微不同地输入它并按列的顺序播放,以便最容易检查您想要比较的内容。但是,这个输出是一个三维数组,与data.frame有很大的不同。
(替代用法示例)
prop.table(with(test, table(src, obs, len) ))