在R中创建交错图表

4

我有一个看起来像这样的数据框:

df <- data.frame(
  CM = c("Jan", "Jan", "Jan", "Feb", "Feb", "Mar", "Mar", "Mar", "Apr", "Apr", "Apr"),
  PM = c("Jan", "Feb", "Mar", "Feb", "Mar", "Mar", "Apr", "May", "Apr", "May", "Jun"),
  Value = c(8, 5, 6, 8, 3, 4, 7, 6, 7, 1, 3))
< p >< em >(其中CM表示当前月份,PM表示预测月份)

df

CM   PM   Value
Jan  Jan  8*
Jan  Feb  5
Jan  Mar  6
Feb  Feb  8*
Feb  Mar  3
Mar  Mar  4*
Mar  Apr  7
Mar  May  6
Apr  Apr  7*
Apr  May  1
Apr  Jun  3

我想将这个整洁的数据转换成一个错开的图表。

       Prediction
       Jan   Feb   Mar   Apr   May   Jun  ...
M|Jan  8*    5     6
O|Feb        8*    3
N|Mar              4*    7     6
T|Apr                    7*    1     3
H|...
表示实际值。

请提供一个可重现的示例,这样我们就不必创建您的数据了。 - Spacedman
“stagger chart”是指瀑布图(也称为步进图或阶梯图)吗? - lawyeR
@lawyeR 我不这么认为。我希望输出结果与我的输出表相似。 - emehex
你的样本数据中没有星号,它们来自哪里?只有在对角线上吗?你想在打印时看到星号吗? - Spacedman
@Spacedman 输出不需要包含星号。我只想以某种方式识别或视觉表示CM = PM的交集。 - emehex
1
我根据你的原始数据框提供了一个解决方案,但是星号有什么作用?只是为了提及对角线项吗? - Colonel Beauvel
3个回答

3
您可以使用reshape2包中的dcast函数:
library(reshape2)
df <- data.frame(
  CM = c("Jan", "Jan", "Jan", "Feb", "Feb", "Mar", "Mar", "Mar", "Apr", "Apr", "Apr"),
  PM = c("Jan", "Feb", "Mar", "Feb", "Mar", "Mar", "Apr", "May", "Apr", "May", "Jun"),
  Value = c(8, 5, 6, 8, 3, 4, 7, 6, 7, 1, 3))
df$CM<-factor(df$CM,levels=month.abb)
df$PM<-factor(df$PM,levels=month.abb)
dcast(df,CM~PM,value.var="Value",fill="")

请使用以下示例:

   CM Jan Feb Mar Apr May Jun
1 Jan   8   5   6            
2 Feb       8   3            
3 Mar           4   7   6    
4 Apr               7   1   3  

添加星标:
res<-dcast(df,CM~PM,value.var="Value",fill="")
row.names(res)<-res[,1]
res<-res[,-1]

for(i in 1:nrow(res)){
  res[i,i]<-paste0(res[i,i],"*")
}
res

提供:

    Jan Feb Mar Apr May Jun
Jan  8*   5   6            
Feb      8*   3            
Mar          4*   7   6    
Apr              7*   1   3

使用 levels=unique(data$C.M)(和 $P.M)可以节省一些打字并保持顺序。除非数据已经是因子(我们不知道!!!),否则使用 month.abb 来表示所有12个月份。 - Spacedman
感谢您的评论,已将其更改为 month.abb 以获得正确的顺序。 - NicE
@NicE,为什么我的“可再生”的df没有输出我的初始打印呢? - emehex
删除“示例”,你正在制作随机数据框,我在我的答案中进行了更改。 - NicE

1
根据您在df中的数值,您可以尝试以下操作:
>df$CM<-factor(df$CM,levels=month.abb)
>df$PM<-factor(df$PM,levels=month.abb) 
>xtabs(Value ~ CM + PM, df)

     PM
CM    Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
  Jan   8   5   6   0   0   0   0   0   0   0   0   0
  Feb   0   8   3   0   0   0   0   0   0   0   0   0
  Mar   0   0   4   7   6   0   0   0   0   0   0   0
  Apr   0   0   0   7   1   3   0   0   0   0   0   0
  May   0   0   0   0   0   0   0   0   0   0   0   0
  Jun   0   0   0   0   0   0   0   0   0   0   0   0
  Jul   0   0   0   0   0   0   0   0   0   0   0   0
  Aug   0   0   0   0   0   0   0   0   0   0   0   0
  Sep   0   0   0   0   0   0   0   0   0   0   0   0
  Oct   0   0   0   0   0   0   0   0   0   0   0   0
  Nov   0   0   0   0   0   0   0   0   0   0   0   0
  Dec   0   0   0   0   0   0   0   0   0   0   0   0

理想情况下,我希望输出的月份是按顺序排列的,并且没有零占位符。 - emehex
为什么不用零呢?您有数字值,但在这种情况下,您只是将它们损坏为字符。此外,如果您需要排序,可以使用 order,尽管我不明白为什么会如此必要。 - Colonel Beauvel

0
您可以使用以下工具:
data<- structure(list(C.M = structure(c(3L, 3L, 3L, 2L, 2L, 4L, 4L, 
4L, 1L, 1L, 1L), .Label = c("Apr", "Feb", "Jan", "Mar"), class = "factor"), 
    P.M = structure(c(3L, 2L, 5L, 2L, 5L, 5L, 1L, 6L, 1L, 6L, 
    4L), .Label = c("Apr", "Feb", "Jan", "Jun", "Mar", "May"), class = "factor"), 
    Value = structure(c(8L, 4L, 5L, 8L, 2L, 3L, 6L, 5L, 7L, 1L, 
    2L), .Label = c("1", "3", "4*", "5", "6", "7", "7*", "8*"
    ), class = "factor")), .Names = c("C.M", "P.M", "Value"), class = "data.frame", row.names = c(NA, 
-11L))

df <- as.data.frame(reshape(data,idvar="C.M",timevar="P.M",direction="wide"))
    print (df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接