2012-09-05 28 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