【问题标题】:Tidyr's gather() with NAsTidyr 的带有 NA 的 collect()
【发布时间】:2015-05-11 08:26:31
【问题描述】:

我正在使用tidyrlubridate 将宽表转换为长表。以下工作正常。

> (df <- data.frame(hh_id = 1:2,
                   bday_01 = ymd(20150309),
                   bday_02 = ymd(19850911),
                   bday_03 = ymd(19801231)))

  hh_id    bday_01    bday_02    bday_03
1     1 2015-03-09 1985-09-11 1980-12-31
2     2 2015-03-09 1985-09-11 1980-12-31

> gather(df, person_num, bday, starts_with("bday_0"))

  hh_id  person_num        bday
1     1     bday_01  2015-03-09
2     2     bday_01  2015-03-09
3     1     bday_02  1985-09-11
4     2     bday_02  1985-09-11
5     1     bday_03  1980-12-31
6     2     bday_03  1980-12-31

但是,当混合中有 NA 时,日期将转换为字符串。

> (df <- data.frame(hh_id = 1:2,
                   bday_01 = ymd(20150309),
                   bday_02 = ymd(19850911),
                   bday_03 = NA))

  hh_id    bday_01    bday_02    bday_03
1     1 2015-03-09 1985-09-11         NA
2     2 2015-03-09 1985-09-11         NA

> gather(df, person_num, bday, starts_with("bday_0"))

  hh_id person_num       bday
1     1    bday_01 1425859200
2     2    bday_01 1425859200
3     1    bday_02  495244800
4     2    bday_02  495244800
5     1    bday_03         NA
6     2    bday_03         NA
Warning message:
attributes are not identical across measure variables; they will be dropped 

请注意,当常规字符串也与 NA 混合时,仍然会出现警告。

> (df <- data.frame(hh_id = 1:2,
                    bday_01 = '20150309',
                    bday_02 = '19850911',
                    bday_03 = NA))

  hh_id  bday_01  bday_02 bday_03
1     1 20150309 19850911      NA
2     2 20150309 19850911      NA

> gather(df, person_num, bday, starts_with("bday_0"))

  hh_id person_num     bday
1     1    bday_01 20150309
2     2    bday_01 20150309
3     1    bday_02 19850911
4     2    bday_02 19850911
5     1    bday_03     <NA>
6     2    bday_03     <NA>
Warning message:
attributes are not identical across measure variables; they will be dropped 

是否可以将 tidyr 与 NA 一起使用,同时避免警告并保留格式?

【问题讨论】:

  • 你可以使用base reshape吗?它没有那个问题reshape(df, idvar = 'hh_id', varying = list(2:4), v.names = 'bday', direction = 'long', timevar = 'person_num')

标签: r lubridate tidyr


【解决方案1】:

数据没有被转换为字符串,它正在回退到自 1970 年 1 月 1 日以来秒的整数表示,这就是 df 中的原始 Date 值所表示的:

x <- df$bday_01
x
#[1] "2015-03-09 UTC" "2015-03-09 UTC"
attributes(x) <- NULL
x
#[1] 1425859200 1425859200

警告消息为您提供了解决方法的提示:

测量变量的属性不相同;他们会 掉了

那么,试试吧:

attributes(df$bday_03) <- attributes(df$bday_02)
gather(df, person_num, bday, starts_with("bday_0"))

#  hh_id person_num       bday
#1     1    bday_01 2015-03-09
#2     2    bday_01 2015-03-09
#3     1    bday_02 1985-09-11
#4     2    bday_02 1985-09-11
#5     1    bday_03       <NA>
#6     2    bday_03       <NA>

【讨论】:

  • 啊,好吧。关于如何系统地为所有 NA 分配属性的想法?换句话说,如果 bday_03 只有一个 NA 而 bday_02 有相反的 NA 呢?
  • @josiekre - 只有当变量中没有任何有效日期的所有 NA 都存在时,问题才会存在。因此,没有为该变量设置适当的日期/时间属性。在 bday_03 和/或 bday_02 的有效日期之间穿插 NA 不会破坏我认为的任何内容。
  • 由于某种原因它确实中断了。这就是我的重要示例:在 lubridate 列中散布 NA。
  • @josiekre - 我无法复制问题,例如:(df &lt;- data.frame(hh_id = 1:2,bday_01 = ymd(20150309,NA),bday_02 = ymd(NA,19850911),bday_03 = NA)) 仍然可以使用此方法。
  • 奇数。 df 对我不起作用。它会删除属性并发出警告。 R 是版本 3.1.2;润滑 1.3.3; tidyr 0.2.0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
相关资源
最近更新 更多