基于基本R reshape()中的因子级别创建列

时间:2013-07-19 22:24:30

标签: r reshape

我正在编写代码以生成有关研究对象及其后续访问时间的报告。我的数据看起来像这样:

subj_id  timepoint           date
    100    3 month     2013-01-01
    101    3 month     2013-01-12
    102    3 month     2013-02-01
    ...        ...            ...

我想将其转换为“宽”数据框,然后我可以合并到另一个数据框中,该数据框显示应该在何时看到主题。使用reshape,我可以做到这一点,但我遇到了以下问题:如果我重塑数据框,我只获得尽可能多的列,因为它在timepoint变量中找到实际变量,即使在那里是数据库中尚未遇到的可能值。

因此,在我的示例中,变量timepoint是一个包含四个级别的因素:3个月,6个月,9个月和12个月。然而,在研究的这一点上,我们没有人经过3个月的访问,所以数据只是上面的100,101和102行。

使用以下命令,您可以获得我所看到的内容(显然这不是我的数据创建方式):

test_df <- data.frame(subj_id=c(100,101,102),
                      timepoint=c("3 month","3 month","3 month"),
                      date=c(as.Date("2013-01-01"),
                             as.Date("2013-01-12"),
                             as.Date("2013-02-01")))

test_df$timepoint <- factor(x=test_df$timepoint,
                            levels=c("3 month","6 month",
                                     "9 month","12 month"),
                            labels=c("3 month","6 month",
                                     "9 month","12 month"),
                            ordered=TRUE)

print(test_df)
>    subj_id timepoint       date
>  1     100   3 month 2013-01-01
>  2     101   3 month 2013-01-12
>  3     102   3 month 2013-02-01

levels(test_df$timepoint)
>  [1] "3 month"  "6 month"  "9 month"  "12 month"

reshape(data=test_df,v.names="date",
        timevar="timepoint",idvar="subj_id",direction="wide")

>    subj_id date.3 month
>  1     100   2013-01-01
>  2     101   2013-01-12
>  3     102   2013-02-01

我想得的是这样的:

>    subj_id date.3 month  date.6 month  date.9 month  date.12 month
>  1     100   2013-01-01            NA            NA             NA
>  2     101   2013-01-12            NA            NA             NA
>  3     102   2013-02-01            NA            NA             NA

有没有办法在基地reshape中执行此操作?我目前的想法是在我运行reshape之前放入四个“假”记录,这样它将会看到四个级别并相应地创建数据框,但这似乎充其量只是笨拙。还有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

这是一种以编程方式扩展数据框以添加未填充级别的列的方法。:

> new_df <- reshape(data=test_df,
+         timevar="timepoint",idvar="subj_id",direction="wide" )
> new_df
  subj_id date.3 month
1     100   2013-01-01
2     101   2013-01-12
3     102   2013-02-01
> new_df[ ,  setdiff(levels(test_df$timepoint) ,
                       factor(test_df$timepoint)) ] <- NA
> 
> new_df
  subj_id date.3 month 6 month 9 month 12 month
1     100   2013-01-01      NA      NA       NA
2     101   2013-01-12      NA      NA       NA
3     102   2013-02-01      NA      NA       NA

注意:这些列名称始终需要引用,因为它们有空格。我从不允许列名保持这种状态。