2012-09-05 29 views
4

我想转置类似于下面的my.data的数据集,然后对这些行进行求和。转置数据集

my.data <- "landuse units year county.a county.b county.c county.d 
      apple acres 2010  0   2   4   6 
      pear acres 2010 10  20  30  40 
      peach acres 2010 500  400  300  200" 

my.data2 <- read.table(textConnection(my.data), header = T) 
my.data2 

所需的输出是:

counties all.fruit 
county.a  510 
county.b  422 
county.c  334 
county.d  246 

我可以用下面的代码执行此操作。但是,下面的代码似乎是一定是巨大的矫枉过正。我希望有一个更简单的解决方案。

# transpose the data set 

tmy.data2 <- t(my.data2) 
tmy.data2 <- as.data.frame(tmy.data2) 

# assign row names to the data set 

my.rows <- row.names(tmy.data2) 

transposed.data <- cbind(my.rows, tmy.data2) 
transposed.data 

# extract numbers to obtain row sums 

fruit.data <- as.data.frame(transposed.data[4:dim(transposed.data)[1], 2:dim(transposed.data)[2]]) 

fruit.data2 <- as.matrix(fruit.data) 

fruit.data3 <- matrix(as.numeric(fruit.data2), nrow=(dim(fruit.data2)[1]), byrow=F) 

# sum fruit by county 

all.fruit <- rowSums(fruit.data3, na.rm=T) 

# create row names for summed fruit data 

counties <- my.rows[4:length(my.rows)] 

almost.final.data <- cbind(counties, all.fruit) 

really.final.data <- as.data.frame(almost.final.data) 

really.final.data[,2] <- as.numeric(as.character(really.final.data[,2])) 
really.final.data 

str(really.final.data) 

谢谢你的任何建议。我可以使用上面的代码,但查看这个请求是一个大大提高我的编程的机会。

+2

为什么不只是'colSums(my.data2 [,4:7])'? (这会得到一个有名的向量,但将其转换为数据帧会很容易)。真正的问题比这更复杂吗? –

+0

感谢您的建议。我猜想,一旦我开始考虑我所关注的行数,甚至不考虑列总和。 –

+1

如果可以的话,我会给你+10来展示你的尝试。 –

回答

7

我只想子集"county"列,总和他们,并使用结果创建一个data.frame:

out <- colSums(my.data2[,grepl("county",colnames(my.data2))]) 
out2 <- data.frame(counties=names(out), all.fruit=out, 
      row.names=NULL, stringsAsFactors=FALSE) 
9

为什么不能直接添加列?

colSums(my.data2[, 4:7]) 

library(plyr) 
numcolwise(sum)(my.data2) 
    year county.a county.b county.c county.d 
1 6030  510  422  334  246 
> 

这就是说,如果你想重新组织有很多选择。该reshape2包提供愉快的语法:

library(reshape2) 
> my.data.melt <- melt(my.data2, id.vars=c('units', 'year', 'landuse')) 
> my.data.melt 
    units year landuse variable value 
1 acres 2010 apple county.a  0 
2 acres 2010 pear county.a 10 
3 acres 2010 peach county.a 500 
4 acres 2010 apple county.b  2 
5 acres 2010 pear county.b 20 
6 acres 2010 peach county.b 400 
7 acres 2010 apple county.c  4 
8 acres 2010 pear county.c 30 
9 acres 2010 peach county.c 300 
10 acres 2010 apple county.d  6 
11 acres 2010 pear county.d 40 
12 acres 2010 peach county.d 200 

我会再使用plyr

> library(plyr) 
> ddply(my.data.melt, .(variable), summarise, all.fruit=sum(value)) 
    variable all.fruit 
1 county.a  510 
2 county.b  422 
3 county.c  334 
4 county.d  246 
> 

你也可以做到这一点使用基础R aggregatedata.table包。

data.table

> library(data.table) 
> my.data.melt <- as.data.table(melt(my.data2, id.vars=c('units', 'year', 'landuse'))) 
> my.data.melt[,list(all.fruit = sum(value)), by = variable] 
    variable all.fruit 
1: county.a  510 
2: county.b  422 
3: county.c  334 
4: county.d  246 

,或者如果你想让它留在格式

> DT <- as.data.table(my.data2) 
> DT[, lapply(.SD, sum, na.rm=TRUE), .SDcols = grep("county",names(DT))]) 
    county.a county.b county.c county.d 
1:  510  422  334  246 

# NB: This needs v1.8.3. Before that, an as.data.table() call was required as 
# the lapply(.SD,...) used to return a named list in this no grouping case. 

> aggregate(value~variable, my.data.melt, sum) 
    variable value 
1 county.a 510 
2 county.b 422 
3 county.c 334 
4 county.d 246 
+0

@mnel我对你的data.table编辑做了3次修改:i)不需要用'as.data.table'封装'lapply'的结果(事实上,这样做会减慢速度,因为它会阻止优化)ii)如果变量名“T”存在于任何地方(特别是如果'T'是值'FALSE'),则'T'变为'TRUE',并且iii)通过使用'grep避免重复一次'DT'变量名...,值= TRUE)'。虽然只是微小的变化。 –

+0

@ mnel哦,等一下,没有分组 - 那是为什么?我现在很困惑。也许还会恢复我的更改。刚刚意识到'value = TRUE'位也可以被删除,因为'.SDcols'接受列号。 –

+0

@mnel和Matthew Dowle,感谢您的编辑!答案现在更加完整。 – Justin