【问题标题】:R. Handling dates and wide format from an imported Stata fileR. 处理导入的 Stata 文件中的日期和宽格式
【发布时间】:2015-05-30 05:04:01
【问题描述】:

我收到了一个 Stata 数据文件 (counts.dta),其中包含 1975 年至 2006 年以宽格式存储的每日计数。这些列标记为月份(作为字符串的月份的全名)、日期(数值为 1-31 的数字),然后是从 1975 年到 2006 年的年份,标签为 '_1975'、'_1976' ... '_2006' .我认为下划线是Stata中某些东西的结果。当年份列不是闰年时,为 2 月 29 日的日期插入了零 (0) 的虚拟计数。

我想做几件事。首先,将年份转换为具有合理表示的长格式。其次,将日期的三方表示改为更合理的方式。

我的方法是将字符串月份更改为一个因子,然后将其调整为正确的顺序:

require("foreign")

counts <- read.dta(file='counts.dta')
counts[['month']] <- as.factor( counts[['month']] )
counts[['month']] <- 
  factor(counts[['month']], levels( counts[['month']] )[c(5,4,8,1,9,7,6,2,12,11,10,3)])

然后我有

str( counts )

'data.frame':   366 obs. of  34 variables:
 $ month: Factor w/ 12 levels "January","February",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ day  : int  1 2 3 4 5 6 7 8 9 10 ...
 $ _1975: int  515 649 745 599 445 667 725 749 646 740 ...
 $ _1976: int  485 685 529 467 630 723 712 685 715 504 ...
 $ _1977: int  505 437 489 588 634 734 682 537 453 673 ...

等等。转换为长格式

lcounts <- reshape(counts,
  direction="long", 
  varying=list(names( counts )[3:34]), 
  v.names="n.counts", 
  idvar=c("month","day"), 
  timevar="Year", 
  times=1975:2006)

str( lcounts )

给予

'data.frame':   11712 obs. of  4 variables:
 $ month   : Factor w/ 12 levels "January","February",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ day     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ Year    : int  1975 1975 1975 1975 1975 1975 1975 1975 1975 1975 ...
 $ n.counts: int  515 649 745 599 445 667 725 749 646 740 ...

加上一些与原始Stata文件相关的更多行。

我的问题是:(1) 现在有什么好方法可以将因子月份、数字年份和数字日期转换为有用的日期格式,以便我可以确定例如星期几,两个日期之间的间隔等等? (2) 有没有更好的方法从一开始就解决这个问题?

【问题讨论】:

  • @ExperimenteR OP 已经在 R 中加载了数据。该建议无助于解决所提出的实际问题。
  • @Thomas 我支持诸如 ExperimeteR 之类的 cmets,这些 cmets 可能对附近地区有所帮助,即解决与发布的问题非常相似但不完全相同的问题。自然,仍然有一个关于在哪里划定界限的判断要求,但 OP 确实在他们的 (2) 下要求更广泛的评论,考虑到一个提供具体细节的主要问题,这似乎是合理的。

标签: r date import dataframe stata


【解决方案1】:

这应该很容易,因为您只需将 data.frame 的行粘贴在一起并使用as.Date 创建一个 Date 类向量。

让我们从一些与你类似的数据开始:

dat <- data.frame(month = c(rep("January",31), rep("February",29)),
                  day = c(1:31, 1:29),
                  Year = 1975,
                  n.counts = 515)

那么日期变量的创建就很简单了:

dat$Date <- as.Date(with(dat, paste(as.numeric(month), day, Year)), "%m %d %Y")
str(dat)
# 'data.frame':   60 obs. of  5 variables:
#  $ month   : Factor w/ 2 levels "February","January": 2 2 2 2 2 2 2 2 2 2 ...
#  $ day     : int  1 2 3 4 5 6 7 8 9 10 ...
#  $ Year    : num  1975 1975 1975 1975 1975 ...
#  $ n.counts: num  515 515 515 515 515 515 515 515 515 515 ...
#  $ Date    : Date, format: "1975-02-01" "1975-02-02" "1975-02-03" "1975-02-04" # ...

【讨论】:

  • 我明白了;换句话说,创建一个全新的日期结构,与我对现有数据结构的先验知识一起使用。非常好。
  • 说了“nice”之后,我认为实际上很尴尬。需要为 1975 年到 2006 年的每一年构建 366 次重复,并为每个月的日期和月份名称做类似的事情。实际上是否有一种方法,比我在我的问题中提出的方法更简单,用于 (a) 达到我已经达到的目的,以及 (b) 将有关日期的信息转换为日期格式。即使保留初始部分并找到一种将日期信息转换为日期结构的简单方法,我也会非常高兴。
  • @user02814 上面你需要运行的唯一行是as.Date(...) 其他东西只是提供一个类似于你的数据结构来显示方法。拥有长格式数据(因为你已经拥有它)的优点是你可以在一行代码中创建一个日期类型的向量。如果你保持宽结构,它会复杂得多。
【解决方案2】:

这个线程的主要焦点自然是数据导入后在 R 中做什么,但这里我将 Stata 方面的各种细节捆绑在一起。

长期以来的建议是,此类数据在 Stata 中更容易以长形处理,reshape long 是一个标准命令,用于对带有单独变量中的每年数据的数据进行转换(R 用户:请阅读“列”作为翻译)。因此,如果可能,您应该在导出之前要求此类 Stata 文件的提供者这样做。

OP 所称的_1975 等标签是 Stata 中的合法变量名,并且正如 OP 猜测的那样,需要下划线,因为 Stata 中的变量名可能不以数字字符开头。

根据给出的信息,可以从 Stata 以.dta 以外的文件格式导出数据而不会丢失数据,特别是作为通常类型的文本文件(.csv 等)。

Stata 保存每日日期的首选方式是整数,其原点为 0 = 1960 年 1 月 1 日(因此 2015 年 3 月 26 日将是 20173),这可能很容易转换为 R 中的任何日期表示。

简而言之,呈现给 OP 的数据的特定且确实奇特的形式在任何意义上都不是任何 Stata 语法所要求的,甚至不推荐作为良好 Stata 实践的一部分。

【讨论】:

  • “开放数据”的乐趣之一是对获取所需数据的方式没有太多控制!事实证明,在我看来,我的问题的解决方案是从 Thomas 那里得到一个建议......我忽略了一些......那就是使用 as.Date 在其中创建一个新的日期变量我的原始数据框使用变量的方式与 Thomas 建议的方式大致相同。但要这样做,我(认为)仍然需要将月份转换为一个因子,以便最终得到一个数值
  • 对不起。但如果它仍然开放,我无法帮助你需要的 R 语法。我的前提是,理想情况下,线程应该具有超出其中提出的任何特定问题的一些价值,因此我的评论更笼统,仅针对 Stata 方面。
  • 我同意并且当然不打算减少您对从 Stata 导出的建议。事实上,我更笼统地使用您的 cmets 来暗示应该在您使用的任何包中练习良好的数据处理,如果将数据从一个包移动到另一个包,那么利用出口端平台,简化整个流程。
猜你喜欢
  • 1970-01-01
  • 2013-12-24
  • 2021-12-28
  • 1970-01-01
  • 2016-10-19
  • 2013-12-18
  • 2022-10-13
  • 1970-01-01
相关资源
最近更新 更多