我有这种格式的数据框 -
ABC 2 ABC 4 ABC 6 DEF 10 DEF 20
我怎样才能得到这个 -
ABC 2 4 6 DEF 10 20
我尝试了aggregate
函数,但它需要像mean / sum这样的函数作为params。如何直接在行中显示值。
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
#
同样,如果您的数据均衡,split
加rbind
可以为您提供所需的数据。使用来自@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
答案 3 :(得分: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"