如果匹配,则在向量中列出

时间:2012-02-25 17:57:31

标签: r

我有一个带有矢量的数据框,格式如下

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来附加到列表,但我对如何解决这个问题感到有点困惑。

How to add variable key/value pair to list object?

`tapply()` to return data frame

3 个答案:

答案 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.00
编辑:使用split,因为在另一个答案中更清晰。

然后,

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插槽。