2013-07-16 161 views
1

我有以下代码,它可以做我想做的事。但我想知道是否有更简单/更好的方式到达那里?计算平均次数的函数

我这样做的总体目标是我为整体数据建立一个单独的汇总表,因此从中得出的平均值将进入该汇总。

Test <- data.frame(
    ID = c(1,1,1,2,2,2,3,3,3), 
    Thing = c("Apple","Apple","Pear","Pear","Apple","Apple","Kiwi","Apple","Pear"), 
    Day = c("Mon","Tue","Wed") 
) 

countfruit <- function(data){ 
df <- as.data.frame(table(data$ID,data$Thing)) 

df <- dcast(df, Var1 ~ Var2) 
    colnames(df) = c("ID", "Apple","Kiwi", "Pear") 

    #fixing the counts to apply a 1 for if there is any count there: 
    df$Apple[df$Apple>0] = 1 
    df$Kiwi[df$Kiwi>0] = 1 
    df$Pear[df$Pear>0] = 1 

    #making a new column in the summary table of how many for each person 
    df$number <- rowSums(df[2:4]) 

return(mean(df$number))} 

result <- countfruit(Test) 
+0

我很抱歉,我没有完全得到你想要得到的代码是什么,可以扩大一点吗? – nico

回答

1

我认为你的问题复杂化了,这里的小版本保持相同的原理。

df <- table(data$ID,data$Thing) 
mean(rowSums(df>0)) ## mean of non zero by column 

编辑一个线性解决方案:

with(Test , mean(rowSums(table(ID,Thing)>0))) 
+0

太棒了!是的,我有一种感觉我太过于复杂,因此我想我会问:)谢谢。你有什么机会可以解释'与'有什么关系?我在帮助文件中看了一下,但是不能解密它:( – Froom2

+0

'with'在由数据构建的环境中评估R表达式,可能会修改原始数据。因此,在'with(Test,...)'内data.frame测试成为一个环境,所以不需要使用$来访问变量,ID也不需要测试$ ID,通过帮助,去试试例子,别无他法。 – agstudy

0

它看起来像你试图计算每列有多少个非零项。如果是这样,请使用as.logical,它可以将任意非零数字转换为TRUE(又名1),或者只计算一行中零的数量并从相关列的数量中减去。 例如,如果我正确地按照你的代码,你的数据帧是

Var1 Apple Kiwi Pear 
1 1  2 0 1 
2 2  2 0 1 
3 3  1 1 1 

所以,(ncol(df)-1) - length(df[1,]==0)给你的第一行计数。 或者,使用as.logical将所有非零值转换为TRUE又名1并计算感兴趣的列上的rowSums

+0

这也不错,但从agstudy的单行是理想的:) – Froom2

+0

@ Froom2我同意你/你。我决定编写一个迷你教程,介绍如何在'R'中做些事情。 agstudy肯定已经写出了一个干净的解决方案。 –