2012-02-25 2 views
1

У меня есть фрейм данных с векторами в формате, как следующийесли матч, список в векторе

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)) 

Тогда я удалю избыточные идентификаторы.

Я рассмотрел использование tapply и цикл над идентификаторами для добавления в список, но я немного смущен о том, как это сделать.

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

`tapply()` to return data frame

ответ

0

Я бы рекомендовал организовать выход немного по-другому, так что ваш dataframe называется Mod имеет три элемента с именем ID1 , ID2, ID3, и каждый из этих элементов является матрица с двумя столбцами. Так ID2 бы

1 5.00
2 1.00
Edit: с помощью 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 слотов.

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 выше) гораздо лучше data.structure работать с с точки зрения программирования, чем конечная продукция вы просили.

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) 
+0

Немного постфактум, но я просто хотел сказать, что это было прекрасно. Именно то, что я хотел, хотя решение Карла работает. Если бы я мог, я бы поднял голову. Огромное спасибо. –

Смежные вопросы