2013-10-05 40 views
-2

我想计算基于两个分组(门和环境)的平均值(以及其他计算),我想重定向到输出到一个文件。我知道下面的代码有效。R函数不返回预期的向量

new_df = myDF[(myDF$Environment=='Water_MarineTreated') & (myDF$Phylum=='Acidobacteria'),] 
print(mean(new_df$pH)) 

但是,因为有这么多的环境和众多的门,我觉得包含循环的函数是最好的方法。我有一个函数,它将一个矢量的名称和计算的名称(例如mean,sd,var等)循环通过每个环境和每个门,计算每个置换的平均pH值,并将其添加到矢量,并返回矢量。不幸的是,返回值是“数字(0)”。虽然这正在返回我告诉它,但这不是我想要的。

我认为规则是每个职位的一个问题,所以如果有人可以解释为什么有一个空的向量返回,而不是一个向量填充pH值的手段,我将不胜感激。如果规则可以稍微弯曲一些,并且有人可以回答为什么“eName = numeric()”不起作用,我也会很感激。如果我在内部循环中放置一个虚拟打印语句,那么当我使用eName = numeric()时,不会打印任何内容,就像我初始化Water_MarineTreated = numeric()时打印的虚拟语句。

我的功能和函数调用如下。

fileName = 'mini.txt'  
    myDF = read.csv(fileName, header = TRUE, sep = ' ') 
    environment = unique(unlist(myDF$Environment, use.names = FALSE)) 
    phyla = unique(unlist(myDF$Phylum, use.names = FALSE)) 

    Statistics = function(eName, funName) 
    { 
     #eName = numeric() #This approach does not work?!! 
     for (i in environment) 
     { 
      for (j in phyla) 
      { 
      stats_df = myDF[(myDF$Environment==i) & (myDF$Phylum==j),] 

      if (i == deparse(substitute(eName))) 
      { 
       #Water_MarineTreated == c(Water_MarineTreated, funName(as.numeric(stats_df$pH))) 
       eName == c(eName, funName(as.numeric(stats_df$pH))) 
       print('dummy_statement') 
       } 
      } 
     } 
     return(eName) 
    } 

    Water_MarineTreated = numeric() 
    Water_MarineTreated = Statistics(Water_MarineTreated, mean) 
    print(Water_MarineTreated) 

输入的样本是这样的:

Phylum pH Environment 
Acidobacteria 5.4 Water_MarineTreated 
Acidobacteria 6.1 Water_PondTreated 
Acidobacteria 6.1 Water_MarineTreated 
Acidobacteria 5.6 Water_MarineTreated 
Acidobacteria 6.2 Water_MarineTreated 
Deinococcus_Thermus 4.9 Water_MarineTreated 
Firmicutes 5.1 Water_MarineTreated 
Firmicutes 5.5 Water_MarineTreated 

回答

2

你必须在环行的中间:

eName == c(eName, funName(as.numeric(stats_df$pH))) 

双等号==手段进行比较,并返回一个TRUEFALSE,它不会做任何分配。所以eName作为一个空向量开始,并且从未有任何分配给它的东西。这只是我更喜欢<-进行分配的其中一个原因。

即使你切换到一个赋值,它现在的方式是每次迭代都会覆盖这个值,而返回值只是最终值,而不是全部。你需要更多的东西一样:在任何这些案件

eName[i] <- ... 

eName[i,] <- ... 

虽然它往往是简单的使用sapply,而不是一个循环。

+0

我完全看到错误(==!= =)。我改变了它,它返回一个结果。您对覆盖的评论也是正确的。我会修改我的代码或使用其他建议。谢谢。 – cer

2

的(除其他事项外)data.table包提供了一个非常漂亮的语法通过组快速计算等功能。考虑以下示例:

library(data.table) 

# Convert sample data to a data.table: 
dt <- as.data.table(mtcars) 

# Calculate the mean and median mpg by cyl and gear, where carb < 8: 
dt[carb<8, # The "where clause" 
    list(mpg.mean=mean(mpg), mpg.med=median(mpg)), # What you want to calculate 
    by=list(cyl,gear)] # The groups go here 
# cyl gear mpg.mean mpg.med 
#1: 6 4 19.750 20.10 
#2: 4 4 26.925 25.85 
#3: 6 3 19.750 19.75 
#4: 8 3 15.050 15.20 
#5: 4 3 21.500 21.50 
#6: 4 5 28.200 28.20 
#7: 8 5 15.800 15.80 
#8: 6 5 19.700 19.70 

查看documentation了解更多信息。

+1

感谢@Jilber的更正。 – dnlbrky

+0

我对R很新,我不熟悉那个包。我已经安装了它,它完全符合我想要的很少的代码。谢谢。 – cer

2

可以使用plyr包来获得您的解决方案:

library(plyr) 
ddply(mtcars,.(mpg,cyl),colwise(mean)) 

为您的数据,如果你想找到比环境与动物门以外的所有列的平均值(并假设这些数字)

library(plyr) 
ddply(myDF,.(Environment,Phylum),colwise(mean)) 

注意:如果你想要sd,用sd替换mean。