2014-01-21 126 views
1

我有数据帧在这个格式 -R数据帧格式组

 
ABC 2 
ABC 4 
ABC 6 
DEF 10 
DEF 20 

我怎样才能得到这个TO-

 
ABC 2 4 6 
DEF 10 20 

我试过aggregate功能,但它需要像均值功能/总和为参数。我怎么才能直接在行中显示值。

+0

如果列长度相同会怎样? – Harpreet

回答

4
df <- read.table(sep=" ", header=F, text=" 
ABC 2 
ABC 4 
ABC 6 
DEF 10 
DEF 20") 
unstack(df, form=V2~V1) 
# $ABC 
# [1] 2 4 6 
# 
# $DEF 
# [1] 10 20 

unstack在这种情况下产生一个list作为列不具有相同的长度。在长度相同的情况下:

df <- read.table(sep=" ", header=F, text=" 
ABC 2 
ABC 4 
ABC 6 
DEF 10 
DEF 20 
DEF 20") 
t(unstack(df, form=V2~V1)) 
#  [,1] [,2] [,3] 
# ABC 2 4 6 
# DEF 10 20 20 
+0

如果色谱柱长度相同会怎样? – Harpreet

+0

@Harpreet然后'unstack'将返回你想要的转置(即ABC和DEF是列名)。使用't()'会将它重新设置为你所需要的。 – lukeA

+0

谢谢,这工作。 – Harpreet

0

你想获得一个稀疏矩阵吗?您示例中的两行具有不同的长度。尝试函数产生一个列表:

mat<-cbind(
c("ABC","ABC","ABC","DEF","DEF"), 
c(2,4,6,10,20) 
) 

count<-function(mat){ 
    values<-unique(mat[,1]) 
    outlist<-list() 
    for(v in values){ 
     outlist[[v]]<-mat[mat[,1]==v,2] 
    } 
    return(outlist) 
} 
count(mat) 

,这将给你这样的结果:

$ABC 
[1] "2" "4" "6" 

$DEF 
[1] "10" "20" 
2

嘛,有什么看法?他们是否想要为每个类别测量相同的东西?

因为每个类别的观察数量都不相同,所以您无法准确获取与发布的数据帧完全相同的数据。但是如果你给“DEF”添加一个“NA”,你可以做到这一点。

像这样:

ABC 2 4 6 
DEF 10 20 NA 

如果这是你想要的,你可以只使用reshape2的dcast

但是你必须命名意见:

library(reshape2) 
df <- data.frame(obs =c(1:3, 1:2), 
       categories = c(rep("ABC", 3), rep("DEF",2)), 
       values=c(2,4,6,10,20), stringsAsFactors=FALSE) 

df2 <- dcast(df, categories~obs) 

df2 
# categories 1 2 3 
# 1  ABC 2 4 6 
# 2  DEF 10 20 NA 
+1

为'dcast'替代+1。请参阅[我的回答](http://stackoverflow.com/a/21248135/1270695)以获取“事后”创建“obs”列的方法。 – A5C1D2H2I1M1N2O1R2T1

1

要添加到您的选择:

这似乎是一个基本的“长广”重塑的问题,但它缺少一个“时间“变量。这很容易通过使用ave重新创建一个:

ave(as.character(df$V1), df$V1, FUN = seq_along) 
# [1] "1" "2" "3" "1" "2" 
df$time <- ave(as.character(df$V1), df$V1, FUN = seq_along) 

一旦你有一个“时间”变量,使用reshape是非常简单的:

reshape(df, idvar="V1", timevar="time", direction = "wide") 
# V1 V2.1 V2.2 V2.3 
# 1 ABC 2 4 6 
# 4 DEF 10 20 NA 

相反,如果你想要一个list,没有需要时间变量。只需使用split

split(df$V2, df$V1) 
# $ABC 
# [1] 2 4 6 
# 
# $DEF 
# [1] 10 20 
# 

同样,如果你的数据是平衡的,splitrbind可以得到你所需要的。使用@lukeA的样本数据:

df <- read.table(sep=" ", header=F, text=" 
ABC 2 
ABC 4 
ABC 6 
DEF 10 
DEF 20 
DEF 20") 
do.call(rbind, split(df$V2, df$V1)) 
#  [,1] [,2] [,3] 
# ABC 2 4 6 
# DEF 10 20 20