1

我正在尝试为我的主管创建一个专门的摘要“矩阵”,并希望 R 以干净、可读的形式将其导出。因此,我基本上是从头开始创建它,以适应我们的项目。我的问题是我无法弄清楚如何让创建的数据框表现得像导入的数据框,特别是标题。

我最擅长处理带有标题的导入数据帧,并按名称而不是列号调用特定行:

iris$Sepal.Length
with(iris,Sepal.Length)
iris['Sepal.Length']

现在,如果我想创建一个数据框(或矩阵,我不完全确定有什么区别),我尝试了以下方法:

groups<-c("Group 1", "Group 2")
factors<-c("Fac 1", "Fac 2", "Fac 3","Fac 4", "Fac 5")
x<-1:10
y<-11:20
z<-21-30

data<-cbind(groups, factors, x, y, z)
names(data) #returns NULL
data$x #clearly doesn't return the column 'x' since the matrix 'data' has no names

data<-data.frame(cbind(groups, factors, x, y, z))
names(data) #confirms that there are header names 

所以,我创建了一个包含 x、y 和 z 列的数据框,但实际上我没有一个预制的列可以开始。如果我知道会有多少行数据,我可以简单地做:

data<-data.frame(1:10)
data$x<-x
data$y<-y
data$z<-z

我尝试创建一个空数据框,但它是一个大元素,如果我尝试向其附加一个向量(任何长度大于 1),我会收到错误消息:

data<-data.frame(0)
data$x<-x #returns an error

我最好的猜测是通过一次数据来找出我将拥有多长时间的数据行(有几个因子级别,并且汇总矩阵将为每个可能的因子组合都有一行)。然后我可以用一个简单的方法开始数据框:

data<-data.frame(length(n)) #其中 n 将是我将拥有多少行数据

并通过为我想要的每个汇总统计量创建单独的向量并使用 ~$~ 将其附加到数据框来完成。

我尝试使用的另一个解决方案是创建一个矩阵并在我在循环中计算它时填充每个元素。我知道 apply 系列比循环更好,但是为了使我的汇总表适合我的需要,我需要运行一个 apply 函数,然后尝试提取单个数据:

means<-with(iris,tapply(iris[,4],Species,mean))
means[1] #This returns the species and the mean petal width. What I need is the numeric part of this, as I will have my own headers, or possibly a separate summary table for each species.

我不确定从应用输出中提取数字信息是否比简单地构建自己的循环来计算所需的统计数据更好/更容易。这将是一个嵌套循环,首先按组排序(2 次运行),然后是一个内部循环,按因素运行(5 次运行),总共 10 次运行数据。我正在考虑创建一个空矩阵,并在计算时简单地将数据保存在适当的单元格中。同样,我的问题是调用矩阵中的特定行。我努力了:

m<-matrix(0,ncol=5)
m[1,1]<-'Groups'
m[1,2]<-'Factors'
m[1,3]<-'Mean.x'
m[1,4]<-'Mean.y'
m[1,5]<-'Mean.z'

names(m) #Returns NULL

我想要的输出如下所示:

Groups   Factors   Mean.x   Mean.y   Mean.z
Group 1   Fac 1  
Group 1   Fac 2
Group 1   Fac 3

等等,对于组和因素的所有组合。

4

3 回答 3

3

您可以使用ddplyplyr 包:假设您的原始数据框是 mydata,而您存储结果的新数据框是 newdata:

library(plyr)
newdata<-ddply(mydata,.(Groups,Factors),summarize,mean.x=mean(x),mean.y=mean(y),mean.z=mean(z))

例子:mydata<-iris

> newdata<-ddply(mydata,.(Species),colwise(mean))
> newdata
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026
于 2013-08-07T16:15:29.790 回答
2

我认为这就是您要寻找的东西,但是总的来说,我对您的问题感到有些困惑。这基本上将为您提供一个按“组”和“因子”列分组的 x、y 和 z 列中平均值的数据透视表

aggregate(.~groups+factors, data=data, FUN="mean")

    groups factors  x  y z
1  Group 1   Fac 1  1  1 1
2  Group 2   Fac 1  7  6 1
3  Group 1   Fac 2  8  7 1
4  Group 2   Fac 2  3  2 1
5  Group 1   Fac 3  4  3 1
6  Group 2   Fac 3  9  8 1
7  Group 1   Fac 4 10  9 1
8  Group 2   Fac 4  5  4 1
9  Group 1   Fac 5  6  5 1
10 Group 2   Fac 5  2 10 1

或按物种分组的虹膜数据:

aggregate(.~Species, data=iris, FUN="mean")

     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

更新:要仅计算某些列的平均值,您可以仅将数据集的适当列传递给聚合函数(可能调用subset)或修改如下公式:

aggregate(cbind(Sepal.Length,Sepal.Width)~Species, data=iris, FUN="mean")
于 2013-08-07T16:22:13.650 回答
1

我不完全确定这是否是您正在寻找的,但有几个选项可以将“东西”添加到数据框:

  • 要添加变量,只需键入data$newname <- NA(无需知道数据框的长度或传递向量,所有行都将填充NA
  • 追加数据使用rbind(您要添加的数据应该是另一个具有相同变量的数据框)

要修复您的示例,请首先创建一个空数据框并附加数据:

data <- data.frame(x=numeric())
data <- rbind(data, data.frame(x))

上一个示例只有一个变量 (x),但您也可以定义一个包含多个变量且没有行的数据框:

data <- data.frame(x=numeric(),
                   y=numeric(),
                   a=character(),
                   b=factor(levels=c("Factor 1", "Factor 2")))

您不需要知道您将拥有多少行,但您添加的数据需要具有相同的结构。如果不是这种情况,您需要根据需要在两个数据框中创建具有缺失值的列,例如

data1 <- data.frame(x=1:10, y=1)
data2 <- data.frame(y=2, z=100:110)
rbind(data1, data2) # Error

data1$z <- NA
data2$x <- NA
rbind(data1, data2) # Now it works
于 2013-08-07T16:45:10.800 回答