我有一个带有矢量的数据框,格式如下
ID <- c("ID1", "ID1", "ID1", "ID2", "ID2", "ID3")
ModNum <- c(1, 2, 3, 1, 2, 0)
Amnt <- c(2.00, 3.00, 2.00, 5.00, 1.00, 5.00)
df <- data.frame(ID, ModNum, Amnt)
我想要的输出是在数据框“Mod”中创建一个新的向量,类似于
ID Mod
ID1 ((1,2.00), (2, 3.00), (3, 2.00))
ID2 ((1, 5.00), (2, 1.00))
ID3 ((0, 5.00))
然后我会删除冗余ID。
我已经考虑过使用tapply和循环ID来附加到列表,但我对如何解决这个问题感到有点困惑。
答案 0 :(得分:1)
以下是使用split()
的解决方案。
> ID.split <- split(df[-1], df$ID)
> ID.split
$ID1
ModNum Amnt
1 1 2
2 2 3
3 3 2
$ID2
ModNum Amnt
4 1 5
5 2 1
$ID3
ModNum Amnt
6 0 5
>
> flat.list <- lapply(ID.split, function(x)as.vector(t(x)))
> df <- data.frame(ID = names(flat.list))
> df$Mod <- flat.list
> df
ID Mod
1 ID1 1, 2, 2, 3, 3, 2
2 ID2 1, 5, 2, 1
3 ID3 0, 5
我认为split()
(上面我称之为ID.split
)的输出是一个更好的数据结构,从编程的角度来看,比你要求的最终输出要好。
答案 1 :(得分:1)
plyr package的另一个解决方案:
df$Mod <- sprintf("(%i, %.2f)", df$ModNum, df$Amnt) # prepare format
library(plyr)
ddply(df, .(ID), summarise, Mod=paste(Mod, collapse=", "))
# ID Mod
# 1 ID1 (1, 2.00), (2, 3.00), (3, 2.00)
# 2 ID2 (1, 5.00), (2, 1.00)
# 3 ID3 (0, 5.00)
答案 2 :(得分:0)
我建议稍微改变输出的组织方式,以便名为Mod
的数据框有三个名为ID1 , ID2, ID3
的元素,每个元素都是一个包含两列的矩阵。所以ID2
将是
1 5.00
编辑:使用
2 1.00split
,因为在另一个答案中更清晰。
然后,
Rgames> df<-as.list(1:length(unique(ID)))
Rgames> names(df)<-unique(ID)
Rgames> df$ID1<-cbind(ModNum[ID=="ID1"],Amnt[ID=="ID1"])
Rgames> df
$ID1
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 2
$ID2
[1] 2
$ID3
[1] 3
当然,您可以循环或lapply
填写所有ID插槽。