【问题标题】:Combine Multiple Columns Into Tidy Data [duplicate]将多列组合成整洁的数据[重复]
【发布时间】:2015-04-28 01:34:48
【问题描述】:

我的数据集如下所示:

unique.id abx.1    start.1     stop.1 abx.2    start.2     stop.2 abx.3    start.3     stop.3 abx.4    start.4
1         1  Moxi 2014-01-01 2014-01-07  PenG 2014-01-01 2014-01-07 Vanco 2014-01-01 2014-01-07  Moxi 2014-01-01
2         2  Moxi 2014-01-01 2014-01-02 Cipro 2014-01-01 2014-01-02  PenG 2014-01-01 2014-01-02 Vanco 2014-01-01
3         3 Cipro 2014-01-01 2014-01-05 Vanco 2014-01-01 2014-01-05 Cipro 2014-01-01 2014-01-05 Vanco 2014-01-01
4         4 Vanco 2014-01-02 2014-01-03 Cipro 2014-01-02 2014-01-03 Cipro 2014-01-02 2014-01-03  PenG 2014-01-02
5         5 Vanco 2014-01-01 2014-01-02  PenG 2014-01-01 2014-01-02  PenG 2014-01-01 2014-01-02 Cipro 2014-01-01
      stop.4    intervention
1 2014-01-07       0
2 2014-01-02       0
3 2014-01-05       1
4 2014-01-03       1
5 2014-01-02       0

用一些代码来创建这个:

 abxoptions <- c("Cipro", "Moxi", "PenG", "Vanco")
      df3 <- data.frame(
      unique.id = 1:5,
      abx.1 = sample(abxoptions,5, replace=TRUE),
      start.1 = as.Date(c('2014-01-01', '2014-01-01', '2014-01-01', '2014-01-02', '2014-01-01')),
      stop.1  = as.Date(c('2014-01-07', '2014-01-02', '2014-01-05', '2014-01-03', '2014-01-02')),
      abx.2 = sample(abxoptions,5, replace=TRUE),         
      start.2 = as.Date(c('2014-01-01', '2014-01-01', '2014-01-01', '2014-01-02', '2014-01-01')),
      stop.2  = as.Date(c('2014-01-07', '2014-01-02', '2014-01-05', '2014-01-03', '2014-01-02')),
      abx.3 = sample(abxoptions,5, replace=TRUE),         
      start.3 = as.Date(c('2014-01-01', '2014-01-01', '2014-01-01', '2014-01-02', '2014-01-01')),
      stop.3  = as.Date(c('2014-01-07', '2014-01-02', '2014-01-05', '2014-01-03', '2014-01-02')),
      abx.4 = sample(abxoptions,5, replace=TRUE),         
      start.4 = as.Date(c('2014-01-01', '2014-01-01', '2014-01-01', '2014-01-02', '2014-01-01')),
      stop.4  = as.Date(c('2014-01-07', '2014-01-02', '2014-01-05', '2014-01-03', '2014-01-02')),
      intervention = c(0,0,1,1,0)

)

我想整理这些数据,使其看起来像这样:

unique.id    abx     start    stop           intervention
1            Moxi    2014-01-10 2014-01-07      0
1            Pen G   2014-01-01 2014-01-07      0
1            Vanco   2014-01-01 2014-01-07      0
1            Moxi    2014-01-01 2014-01-07      0  etc etc

以下解决方案无法将我带到我需要的地方: Gather multiple sets of columnsCombining multiple columns into one

我怀疑 Hadley 惊人的 tidyr pakcage 是要走的路……只是想不通。任何帮助将不胜感激。

【问题讨论】:

  • 已解决问题,谢谢!

标签: r dplyr tidyr


【解决方案1】:

几乎每一个数据整理问题都可以分三步解决:

  1. 收集所有非变量列
  2. 将“colname”列分成多个变量
  3. 重新传播数据

(通常你只需要其中的一两个,但我认为它们几乎总是按这个顺序排列)。

对于您的数据:

  1. 唯一已经是变量的列是unique.id
  2. 您需要将当前列名拆分为变量和数字
  3. 然后您需要将“变量”变量放回列中

这看起来像:

library(tidyr)
library(dplyr)

df3 %>%
  gather(col, value, -unique.id, -intervention) %>%
  separate(col, c("variable", "number")) %>%
  spread(variable, value, convert = TRUE) %>%
  mutate(start = as.Date(start, "1970-01-01"), stop = as.Date(stop, "1970-01-01"))

你的情况有点复杂,因为你有两种类型的变量,所以最后需要恢复类型。

【讨论】:

  • 哈德利。非常感谢您的回复。这解决了它。我不得不在我的实际数据集中删除另一列,它标记了这是否发生在干预阶段(1 或 0)。仍然包含此列,我得到:错误:值未在.675,676 处分成 2 部分......然后属性在度量变量中不相同;他们将被丢弃。我需要进一步阅读您的文档,因为我仍然不完全清楚这里发生了什么。
  • 我建议一次运行一行并查看每个步骤的结果。对于拆分问题,您需要查看要拆分的额外参数。
  • 正是我需要的!问题解决了!
  • 非常喜欢 H Wicks
【解决方案2】:

你可以试试 reshapebase R

reshape(df3, direction='long', varying=2:ncol(df3), sep=".")

或者从splitstackshape使用merged.stack

 library(splitstackshape)
 merged.stack(df3, var.stubs=c('abx', 'start', 'stop'), sep='.')[,
    c('start', 'stop') := lapply(.SD, as.Date,
                   origin='1970-01-01'), .SDcols=4:5][]

【讨论】:

  • 嗯,我在尝试 reshape 方法时遇到错误。我应该注意我的数据框中的数据扩展到 abx.14:猜测错误(变化):无法从它们的名称中猜测时变变量另外:警告消息:在 rbind(c("start", "date") , c("stop", "date"), c("abx", "2"), c("start", : 结果的列数不是向量长度的倍数 (arg 1)
  • @TomO 根据您创建的示例,我没有收到任何错误
  • 你在我的示例数据集中是正确的。
  • @TomO 不知道你是怎么得到这个错误的。我正在使用R 3.1.2。您能否将列名的. 更改为_ 并重试? IE。 names(df3)[-1] &lt;- sub('[.]', '_', names(df3)[-1]);reshape(df3, direction='long', varying=2:ncol(df3), sep="_")
  • @TomO 很高兴为您提供帮助。这里有点晚了。所以,我稍后会检查你的更新。
【解决方案3】:

最近,melt.data.table 添加了一项新功能,可以轻松融入多个列。您所要做的就是在 list in measure.vars 参数中提供您想要单独融化的列。

您可以关注these instructions获取开发版。

require(data.table) ## v1.9.5
setDT(dat) # dat is now a data.table
melt(dat, id = 1L, measure = patterns("^abx", "^start", "^stop"), 
          value.name = c("abx", "start", "stop"))

#     unique.id variable   abx      start       stop
#  1:         1        1  Moxi 2014-01-01 2014-01-07
#  2:         2        1  Moxi 2014-01-01 2014-01-02
#  3:         3        1 Cipro 2014-01-01 2014-01-05
#  4:         4        1 Vanco 2014-01-02 2014-01-03
#  5:         5        1 Vanco 2014-01-01 2014-01-02
#  6:         1        2  PenG 2014-01-01 2014-01-07
#  7:         2        2 Cipro 2014-01-01 2014-01-02
#  8:         3        2 Vanco 2014-01-01 2014-01-05
#  9:         4        2 Cipro 2014-01-02 2014-01-03
# 10:         5        2  PenG 2014-01-01 2014-01-02
# 11:         1        3 Vanco 2014-01-01 2014-01-07
# 12:         2        3  PenG 2014-01-01 2014-01-02
# 13:         3        3 Cipro 2014-01-01 2014-01-05
# 14:         4        3 Cipro 2014-01-02 2014-01-03
# 15:         5        3  PenG 2014-01-01 2014-01-02
# 16:         1        4  Moxi 2014-01-01 2014-01-07
# 17:         2        4 Vanco 2014-01-01 2014-01-02
# 18:         3        4 Vanco 2014-01-01 2014-01-05
# 19:         4        4  PenG 2014-01-02 2014-01-03
# 20:         5        4 Cipro 2014-01-01 2014-01-02

我在这里使用了列号,但您也可以提供列名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2018-04-12
    • 2020-07-29
    • 2011-01-24
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多