从Stata到R:在子集上创建具有垂直日期行的散点图

coi*_*oip 5 graphing r subset ggplot2 stata

介绍

我试图在R中复制我在Stata上创建的数据子集的时间序列散点图.散点图在x轴上具有时间变量'date'(mm/dd/yyyy),在y轴上具有整数变量'cost'(货币金额,以美元计).标记标签是分类变量,"公司名称".

实际的数据集非常大,但样本看起来如下(见下面的R代码),观察(即行)表示交易(第1列),后面跟着表明交易日期的变量(第2列),交易成本(第3列),以及启动交易的公司名称(第4列).

#Sample Data Frame (R Code)

transactionID <- c(1, 2, 3, 4) 
date <- as.Date(c("2006-08-06", "2008-07-30", "2009-04-16", "2013-02-05"))
cost <- as.integer(c(1208, 23820, 402, 89943))
company <- c("ACo", "BInc", "CInd", "DOp")
thedata <- data.frame(transactionID, date, cost, company)
Run Code Online (Sandbox Code Playgroud)

在Stata中完成它

我想要的散点图将在x轴上显示"日期",在y轴上显示"成本",将"公司"列为标记标签,并且还将具有3条各种格式的垂直线来表示重要事件.在Stata中生成这个的步骤是

  1. 在2007年9月10日,2008年1月28日,2012年1月18日和2013年2月5日的日期确定垂直线的x轴点.

显示mdy(9,10,2007)

显示mdy(1,28,2008)

display mdy(2,5,2013)

上面的三个显示命令返回值17419,1755,19394,这是Stata在内部读取那些日子的方式,以及嵌入在下面的代码中用于绘制散点图的图形.

  1. 创建散点图,添加步骤1中的三条垂直线,将它们格式化为红色,蓝色和绿色以及不同厚度的虚线,虚线和实线,并在y轴上显示"成本",日期'在x轴上,'公司'名称作为标记标签,仅适用于小于或等于$ 3,000的交易:

如果成本<= 3000,图表twoway散布成本日期,mla​​bel(公司)xline(17419,lpatt(点)lwidth(厚)lcol(红色))xline(17559,lpatt(破折号)lwidth(medthick)lcol(蓝色))xline (19394,lpatt(实心)lwidth(thin)lcol(绿色))

在R中做的问题

当我试图在RI中复制它时遇到了以下问题

  1. 无法弄清楚如何在这些特定日期添加垂直线,也不知道如何更改它们的大小格式
  2. Y轴('成本')采用科学记数法(即2e + 05)而非常规数字(即200,000)
  3. 我不太了解R中的子集; 在Stata中,我可以轻松添加"if"限定符来检查特定数据子集(例如"if cost> 3000&transactionID <5"),然后轻松修改它们以重新运行分析或在其他各种子集上绘制图形.但是在R中似乎还有一些额外的步骤需要先将数据子集化并将其存储为新对象,然后对该对象运行分析.是对的吗?我看到这一些好处,但也有一些缺点(如具有数百个,为您探索数据,例如搞乱你的工作环境,不同的对象).

到目前为止,我已将以下代码拼凑在一起.我最初尝试使用基本R安装命令plot()和text(),但它似乎无法在基础R中完成.所以然后我尝试使用ggplot2包但仍然无法弄清楚像我可以在Stata:

library(ggplot2)
ggplot(thedata, aes(date, cost)) + 
       geom_text( label = thedata$company, color="blue", vjust = 0) +  
       geom_vline( xintercept = as.numeric( thedata$date[
                      c(I don't know what goes here, or here)]), 
                  linetype="dotted", color="red")
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我无法弄清楚geom_vline命令的xintercept的坐标是如何工作的(并且在官方帮助文件中找不到它),特别是当我希望它们是日期时(特别是可能或不是的日期)在数据框中),我也无法弄清楚如何改变线的粗细.

raw*_*awr 3

问题做得非常好。如果您仍然对基本解决方案感兴趣:

transactionID <- c(1, 2, 3, 4)
date <- as.Date(c("2006-08-06", "2008-07-30", "2009-04-16", "2013-02-05"))
cost <- as.integer(c(1208, 23820, 402, 89943))
company <- c("ACo", "BInc", "CInd", "DOp")
thedata <- data.frame(transactionID, date, cost, company)


par(mar = c(5,7,3,2), tcl = .2, las = 1)
with(thedata, 
     plot(date, cost, xlab = 'Date', ylab = '', axes = FALSE, main = 'a plot'))
dseq <- seq.Date(as.Date('2006-01-01'), as.Date('2013-01-01'), by = 'year')
axis.Date(1, at = dseq, labels = format(dseq, format = '%Y'))
# axis.Date(1, at = seq.Date(min(date), max(date), by = 'year'))
axis(2, at = pretty(cost), 
     labels = format(pretty(cost), scientific = FALSE, big.mark = ','))
## add lines at specified dates
abline(v = as.Date(c('2007-09-10','2008-01-28','2012-01-18')), lwd = 1:3,
       lty = c('dotted','dashed','solid'), col = c('red','blue','green'))
## add company labels
text(x = date, y = cost, pos = 3, xpd = NA,
     labels = ifelse(cost <= 3000, company, ''))
title(ylab = 'Cost', line = 5)
box('plot', bty = 'l')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

解决一些具体问题:

  1. 我用as.Date。R 存储日期的方式与 stata 类似

    abline(v = as.Date(c('2007-09-10','2008-01-28','2012-01-18')), lwd = 1:3,
           lty = c('dotted','dashed','solid'), col = c('red','blue','green'))
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用格式

    format(pretty(cost), scientific = FALSE, big.mark = ',')
    # [1] "      0" " 20,000" " 40,000" " 60,000" " 80,000" "100,000"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果您对此更满意,当然可以创建一些子集,但通常有一种方法可以在 r 中执行单行

    ifelse(cost <= 3000, company, '')
    # [1] "ACo"  ""     "CInd" ""  
    
    Run Code Online (Sandbox Code Playgroud)

大多数基本绘图函数都是矢量化的,这就是为什么这如此简单。而且我不是 ggplot 向导,当我尝试制作像这样的非常特殊格式的绘图时,它通常会让我头疼。一般来说,ggplot 适合绘制漂亮、快速、脏图。如果您想要一些非常具体的东西或想要发布一些东西,那么基本 r 图形是您的最佳选择。

  • 如果您的图表符合哈德利的哲学观点,您可以很容易地生成高质量的图表以供发布(通常比基本图形所需的代码更少)。只有当你想做一些 ggplot2 不支持的事情时,你才会遇到麻烦,最好使用 base。如今,我通常使用基本图来进行快速和肮脏的处理,并使用 ggplot2 进行发布(只要我不需要辅助轴)。 (2认同)