【问题标题】:Better way to use plyr (or other) to create a variable using seq from 2 other variables使用 plyr (或其他)使用 seq 从其他 2 个变量创建变量的更好方法
【发布时间】:2013-04-19 07:21:58
【问题描述】:

我有一些包含入院和出院日期的数据,我需要(为每个人和承认 ID #)创建一个从宽到长的数据框,其中包含人员和承认 ID,其顺序为入院和出院表示介于入院和出院之间(包括入院和出院)的每一天的值。

我偶然发现了一种非常 hack-ish 的方法,它利用了 dlply 如何命名它创建的列表中的项目;但是,我担心它可能容易出错。无论哪种方式,它都感觉很笨拙,我想知道是否有一种使用更少代码的更简洁的方法。

person <- c(1, 2, 3, 3)
admit <- c(1, 1, 1, 2)
admit.date <- as.Date(c("1/1/2010", "1/1/2010", "1/1/2010", "2/1/2010"), "%m/%d/%Y")
discharge.date <- as.Date(c("1/1/2010",  "1/1/2010", "1/1/2010", "2/1/2010"), "%m/%d/%Y") + c(1,2,2,2)
df1 <- data.frame(person, admit, admit.date, discharge.date)
df1 ## where I start

library(plyr)
los_seq <-  function(df) { seq(df$admit.date, df$discharge.date, 1)} 
lst1 <- dlply(df1, .(person, admit), los_seq)
vec1 <- unlist(lst1)
## now it gets really hackish
df2 <- data.frame(v1 = paste(names(vec1), vec1, sep="__"))
df2$person <- substr(df2$v1, 1, regexpr("\\.", df2$v1)-1)
df2$admit <- substr(df2$v1, regexpr("\\.", df2$v1)+1,  regexpr("\\.", df2$v1)+1)
df2$date <- as.Date(as.numeric(substr(df2$v1, regexpr("__", df2$v1)+2,  nchar(df2$v1))), origin="1970-01-01")
df2[,-1]  ##  this is how I need the result to look

【问题讨论】:

  • 请使您的示例可重现。我假设lst1 应该是df2。而且,我在 df2$date 中看不到您要查找的内容。
  • 是的。在重新阅读我的帖子后,我实际上注意到了这个错误,并且几乎立即更改了它(在原始帖子后几分钟)。速度不够快,您不仅无法提出更优雅的解决方案,而且尽管有未经编辑的帖子,也无法推断出我的意图。确实很好......

标签: r plyr


【解决方案1】:

如何使用类似以下的内容(因为您使用的是实际日期):

SEQ <- df1$discharge.date - df1$admit.date + 1
df1[rep(row.names(df1), SEQ), 1:2]
#     person admit
# 1        1     1
# 1.1      1     1
# 2        2     1
# 2.1      2     1
# 2.2      2     1
# 3        3     1
# 3.1      3     1
# 3.2      3     1
# 4        3     2
# 4.1      3     2
# 4.2      3     2

现在,要猜测您在评论中可能指的是什么,也许您也在寻找日期的顺序。

SEQ <- df1$discharge.date - df1$admit.date + 1
df2 <- df1[rep(row.names(df1), SEQ), 1:3]
df2$date <- df2$admit.date + sequence(SEQ)-1
df2[-3]
#     person admit       date
# 1        1     1 2010-01-01
# 1.1      1     1 2010-01-02
# 2        2     1 2010-01-01
# 2.1      2     1 2010-01-02
# 2.2      2     1 2010-01-03
# 3        3     1 2010-01-01
# 3.1      3     1 2010-01-02
# 3.2      3     1 2010-01-03
# 4        3     2 2010-02-01
# 4.1      3     2 2010-02-02
# 4.2      3     2 2010-02-03

【讨论】:

  • 我喜欢你用很少的行在那里做的事情,但我也需要实际日期作为变量(例如,df2["date"])。
  • 太棒了,我最喜欢它的是,它没有使用特殊的包/功能——全部在基础!
  • @Chris,为了我的利益,这是你所追求的答案:)
  • 最后一个,您使用 df2$admit.date + sequence(SEQ)-1 生成日期序列向量。那是纯粹的数据忍术! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 2018-05-31
  • 2023-03-27
  • 2021-02-10
相关资源
最近更新 更多