2013-04-16 28 views
2

我有一個具有沿如何基於列名減少表尺寸

Class1 0.438 0.441 0.442 0.444 0.545 0.546 0.548 0.609 0.651 0.652 0.655 
    DAWO  2  2  0  1  0  0  0  1  1  5  1 
    DRWO  1  1  3  1  1  1  1  0  0  1  0 
    DHWO  1  2  0  0  0  0  0  0  0  0  0 

行的格式,我想通過合併基於列的列名&減少表的尺寸的表添加值。例如

Class1 0.4 0.5 0.6 
    DAWO  5  0  8  
    DRWO  6  3  1  
    DHWO  3  0  0  

這怎麼可能? 在此先感謝您的幫助

回答

1
x <- read.table(header=TRUE, text="  0.438 0.441 0.442 0.444 0.545 0.546 0.548 0.609 0.651 0.652 0.655 
DAWO  2  2  0  1  0  0  0  1  1  5  1 
DRWO  1  1  3  1  1  1  1  0  0  1  0 
DHWO  1  2  0  0  0  0  0  0  0  0  0 ", check.names=F) 

請注意,我沒有複製的文本Class1,使DAW0等,都是在原有的一套行的名稱。

首先,採取轉置,以幫助一個aggregate

tx <- as.data.frame(t(x)) 

這些都是削減。假定值在0和1之間。根據需要進行調整。

tx$bin <- cut(as.numeric(rownames(tx)), breaks=seq(0,1,.1)) 

添加了值,設置名稱,並再次轉回來:

xx <- aggregate(.~bin, data=tx, FUN=sum) 
rownames(xx) <- xx$bin 
t(xx[-1]) 
##  (0.4,0.5] (0.5,0.6] (0.6,0.7] 
## DAWO   5   0   8 
## DRWO   6   3   1 
## DHWO   3   0   0 
1

這裏的另一種選擇。使用@ Matthew的答案中的「x」,您可以使用strtim從您的姓名創建您的類別,然後使用sapply跨過這些類別進行彙總。

mymatch <- strtrim(names(x), 3) 
sapply(unique(mymatch), function(y) rowSums(x[, mymatch == y, drop = FALSE])) 
#  0.4 0.5 0.6 
# DAWO 5 0 8 
# DRWO 6 3 1 
# DHWO 3 0 0 

另外,使用原始數據,你只需要一點點小心,記住要放棄你「的Class1」列取rowSums時:

mymatch <- strtrim(names(mydf), 3)[-1] 
cbind(mydf[1], 
     sapply(unique(mymatch), 
      function(y) rowSums(mydf[-1][, mymatch == y, drop = FALSE]))) 
# Class1 0.4 0.5 0.6 
# 1 DAWO 5 0 8 
# 2 DRWO 6 3 1 
# 3 DHWO 3 0 0 

最後,還有經典「reshape2」 的方式,涉及melt*cast

> library(reshape2) 
> Stacked <- melt(mydf) 
Using Class1 as id variables 
> dcast(Stacked, Class1 ~ strtrim(variable, 3), fun.aggregate=sum) 
    Class1 0.4 0.5 0.6 
1 DAWO 5 0 8 
2 DHWO 3 0 0 
3 DRWO 6 3 1 

在過去的兩個例子,mydf定義爲:

mydf <- structure(list(Class1 = structure(c(1L, 3L, 2L), .Label = c("DAWO", 
"DHWO", "DRWO"), class = "factor"), `0.438` = c(2L, 1L, 1L), 
    `0.441` = c(2L, 1L, 2L), `0.442` = c(0L, 3L, 0L), `0.444` = c(1L, 
    1L, 0L), `0.545` = c(0L, 1L, 0L), `0.546` = c(0L, 1L, 0L), 
    `0.548` = c(0L, 1L, 0L), `0.609` = c(1L, 0L, 0L), `0.651` = c(1L, 
    0L, 0L), `0.652` = c(5L, 1L, 0L), `0.655` = c(1L, 0L, 0L)), 
.Names = c("Class1", "0.438", "0.441", "0.442", "0.444", "0.545", "0.546", 
"0.548", "0.609", "0.651", "0.652", "0.655"), class = "data.frame", 
row.names = c(NA, -3L))