2013-03-14 91 views
1

我需要以不同的方式查看數據框中的數據。這裏的問題..R數據轉換

我有一個數據幀如下

Person Item BuyOrSell 
1  a B 
1  b S 
1  a S 
2  d B 
3  a S 
3  e S 

一個我的要求就是看數據如下。顯示該人對交易類型(B或S)

Person aB aS bB bS dB dS eB eS 
1   1 1 0 1 0 0 0  0 
2   0 0 0 0 1 0 0  0 
3   1 0 0 0 0 0 0  1 

所以我創建了一個新的列和追加兩個項目和BuyOrSell值破個別項目進行的所有交易的總和。

df$newcol<-paste(Item,"-",BuyOrSell,sep="") 
table(Person,newcol) 

並且能夠達到上述結果。

最後轉換的要求這是一個難啃的骨頭是如下....

aB aS bB bS dB dS eB eS 
aB 1 1 0 1 0 0  0 0 
aS 1 2 0 1 0 0  0 1 
bB 0 0 0 0 0 0  0 0 
bS 1 1 0 0 0 0  0 0 
dB 0 0 0 0 1 0  0 0 
dS 0 0 0 0 0 0  0 0 
eB 0 0 0 0 0 0  0 0 
eS 0 1 0 0 0 0  0 1 

,其中上表必須與人誰做特定的交易也讓數填寫另一項目上的交易。

我試過table(newcol,newcol),但它只對aB-aB,aS-aS,bB-bB,......產生計數,而對於所有其他組合則產生0。

關於什麼包或命令會讓我破解這個螺母的想法?

+3

我覺得你應該先接受回答你剛纔的問題:http://stackoverflow.com/questions/15417698/data-transformations-in-r – Arun 2013-03-14 20:55:54

+0

只是。謝謝Arun! – user2171177 2013-03-14 21:01:51

+0

你能解釋一下你的標準嗎?我有一個很難理解「其中上表必須是...另一個項目」 – Arun 2013-03-14 22:16:47

回答

3

不只是最終的結果:

# Following Ricardo's solution for casting, but using `acast` instead 
A <- acast(Person~Item+BuyOrSell,data=df,fun.aggregate=length,drop=FALSE) 

# A' * A 
> t(A) %*% A 
#  a_B a_S b_B b_S d_B d_S e_B e_S 
# a_B 1 1 0 1 0 0 0 0 
# a_S 1 2 0 1 0 0 0 1 
# b_B 0 0 0 0 0 0 0 0 
# b_S 1 1 0 1 0 0 0 0 
# d_B 0 0 0 0 1 0 0 0 
# d_S 0 0 0 0 0 0 0 0 
# e_B 0 0 0 0 0 0 0 0 
# e_S 0 1 0 0 0 0 0 1 
+0

看起來很對我。非常優雅! – 2013-03-14 23:59:37

+0

這是一個很好的答案。 wonderful..thanks。 – user2171177 2013-03-15 01:31:49

1

我認爲有一個更好的方法,但這裏有一個方法使用包reshape2

require(reshape2) 
#reshapes data so each item and buy/sell event interaction occurs once 
df2 <- dcast(Person~Item+BuyOrSell,data=df,fun.aggregate=length,drop=FALSE) 
df2 
    # Person a_B a_S b_B b_S d_B d_S e_B e_S 
# 1  1 1 1 0 1 0 0 0 0 
# 2  2 0 0 0 0 1 0 0 0 
# 3  3 0 1 0 0 0 0 0 1 

#reshapes data so every row is an interaction by person 
df3 <- melt(df2,id.vars="Person") 
head(df3) 
    # Person variable value 
# 1  1  a_B  1 
# 2  2  a_B  0 
# 3  3  a_B  0 
# 4  1  a_S  1 
# 5  2  a_S  0 
# 6  3  a_S  1 

#removes empty rows where no action occurred 
#removes value column 
df4 <- with(df3, 
    data.frame(Person=rep.int(Person,value),variable=rep.int(variable,value)) 
#performs a self-merge: now each row is 
#every combination of two actions that one person has done 
df5 <- merge(df4,df4,by="Person") 
head(df5) 
    # Person variable.x variable.y 
# 1  1  a_B  a_B 
# 2  1  a_B  a_S 
# 3  1  a_B  b_S 
# 4  1  a_S  a_B 
# 5  1  a_S  a_S 
# 6  1  a_S  b_S 

#tabulates variable interactions 
with(df5,table(variable.x,variable.y)) 
+0

你能解釋一下你的解決方案嗎?尤其是DF4 – user2171177 2013-03-14 21:30:40

+0

我改變了'df4'原來是因爲我以爲你會算的人1兩次,如果他們購買了項目A的兩倍,但在重新閱讀的問題,我覺得你只是想的人數。我現在改回來了。 – 2013-03-14 22:32:58

+0

您的初始解決方案非常完美。我會數一次人1。我已經在下面發佈了我的答案..我根據你的解決方案對我所做的不同做了很多。請在下面對我的帖子發表評論。 – user2171177 2013-03-14 22:38:48

0

Blue Magister,您的解決方案完美工作,我分析了您執行的每一步。

DF4的產量如下:

Person variable 
1  1  a_B 
2  1  a_S 
3  3  a_S 
4  1  b_S 
5  2  d_B 
6  3  e_S 

with(df5,table(variable.x,variable.y))產量爲

variable.y 
variable.x a_B a_S b_B b_S d_B d_S e_B e_S 
     a_B 1 1 0 1 0 0 0 0 
     a_S 1 2 0 1 0 0 0 1 
     b_B 0 0 0 0 0 0 0 0 
     b_S 1 1 0 1 0 0 0 0 
     d_B 0 0 0 0 1 0 0 0 
     d_S 0 0 0 0 0 0 0 0 
     e_B 0 0 0 0 0 0 0 0 
     e_S 0 1 0 0 0 0 0 1 

這正是我想要的。

當我看着D4輸出它幾乎類似於我NEWCOL溶液(使用膏)相比,你DF4時

> df 
    Person newcol 
1  1 a-B 
2  1 b-S 
3  1 a-S 
4  2 d-B 
5  3 a-S 
6  3 e-S 

這裏唯一的不同是行的排序。

所以,我結束了在運行此命令

dfx <- merge(df,df,by="Person") 
with(dfx,table(newcol.x,newcol.y)) 

,並生成以下...

newcol.y 
newcol.x a-B a-S b-S d-B e-S 
    a-B 1 1 1 0 0 
    a-S 1 2 1 0 1 
    b-S 1 1 1 0 0 
    d-B 0 0 0 1 0 
    e-S 0 1 0 0 1 

以上輸出忽略幾行和列。我和你有什麼不同?

+0

您應該將此文本移至單獨的問題,而不是通過「答案」詢問。再回到以前的問題,讓人們明白你在問什麼。 – 2013-03-14 22:49:07

+1

本質上,差異源於'levels(df4 $ variable)'和你的'levels(df $ newcol)'。 – 2013-03-14 22:50:47

+0

輝煌!謝謝。 – user2171177 2013-03-15 01:29:37