1

我需要以不同的方式查看数据框中的数据。问题来了。。

我有一个数据框如下

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

所以我创建了一个新列并附加了 Item 和 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。

关于什么包或命令会让我破解这个坚果的任何想法?

4

3 回答 3

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
于 2013-03-14T22:51:32.260 回答
1

我认为有更好的方法,但这里有一个使用 package 的方法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))
于 2013-03-14T21:03:52.660 回答
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 解决方案相似(使用 paste )

> 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

与您的 df4 相比,这里唯一的区别是行的顺序。

所以,我最终运行了这个命令

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

上面的输出忽略了几行和几列。我和你有什么不同?

于 2013-03-14T22:34:42.160 回答