在R中重新格式化表格

在R中重新格式化表格,r,reshape,R,Reshape,我有一个如下表(具有相同ID的不同行将具有相同的性别和年龄值,但不同的类别和子类别值): 通过组合具有相同ID的不同行,我希望如下所示对表进行改革: ID product.category1 sub.category1 product.category2 sub.category2 product.category3 sub.category3 gender age 1 1 food chicken kitchen

我有一个如下表(具有相同ID的不同行将具有相同的性别和年龄值,但不同的类别和子类别值):

通过组合具有相同ID的不同行,我希望如下所示对表进行改革:

  ID product.category1 sub.category1 product.category2 sub.category2 product.category3 sub.category3 gender   age
1  1              food       chicken           kitchen        napkin              food         steak      M young
2  2        electronic         phone              null          null              null          null      F   mid
3  3             cloth         shirt           kitchen          bowl              null          null      M   old
4  4              alch          beer              null          null              null          null      F young
我在R怎么做

# 新数据集:文本变量实际上是注释的文本列

text    Category    Subcategory variable1   variable2   variable3   variable4   date
aaaaa   c1  s11 v1  N   RETAIL  Y   2014-01
aaaaa   c2  s22 v1  N   LEASE   Y   2014-01
aaaaa   c3  s31 v1  N   LEASE   Y   2014-01
bbbbb   c1  s12 v2  N   LEASE   Y   2014-01
ccccc   c2  s21 v1  N   LEASE   Y   2014-01
ddddd   c2  s21 v1  N   RETAIL  Y   2014-01
ddddd   c3  s31 v1  N   LEASE   Y   2014-01
eeeee   c1  s11 v1  N   RETAIL  Y   2014-01
fffff   c2  s21 v2  U   RETAIL  Y   2014-01

谢谢

我们使用了软件包
reforme2
中的
melt
dcast
的组合

library(dplyr)
library(reshape2)
m2 <- melt(df, c("ID", "gender", "age")) %>% group_by(ID, variable) %>% 
  mutate(variable2 = paste0(variable, seq_along(value)))
newdf <- dcast(m2[!names(m2) %in% "variable"], ...~variable2, value.var="value", fill="null")
酷吧?我们利用了这样一个事实,即rbind在按行输入值时将按列展开。在我们的例子中,写
1:3
没有帮助,因为数据中可能有更多的产品。但我们知道有两个标题“产品类别”和“子类别”。我们将
variable2
的唯一值除以2并使用它

n <- nrow(unique(m2[,"variable2"]))
newdf[c(1:3,(c(rbind(1:(n/2), (n/2+1):n))+3))]
#   ID gender   age product.category1 sub.category1 product.category2
# 1  1      M young              food       chicken           kitchen
# 2  2      F   mid        electronic         phone              null
# 3  3      M   old             cloth         shirt           kitchen
# 4  4      F young              alch          beer              null
#   sub.category2 product.category3 sub.category3
# 1        napkin              food         steak
# 2          null              null          null
# 3          bowl              null          null
# 4          null              null          null
n%
突变(variable2=paste0(变量,沿(值)的顺序)

newdfdata.table dcast您可以使用整形2或data.table包中的
dcast

library(data.table)
setDT(DT)

DT[, obsno := 1:.N, by=ID]
res <- dcast(DT, ID+gender+age~obsno, value.var=c("product.category","sub.category"))
要按所需顺序查看列,可以执行以下操作

res[, c(1:3,4,7,5,8,6,9), with=FALSE]
tidyr包也可能采用类似的方法(尽管它不会被称为“dcast”)

我建议对任何分析都坚持使用长格式(您最初使用的格式)。您正在寻找的这种宽格式对于除浏览数据之外的任何内容都非常麻烦


第二个例子是OP的第二个例子,我会

DT2[, obsno := 1:.N, by=text]
dcast(DT2, ...~obsno, value.var=c("Category", "Subcategory"))
从@Pierrelaffortune的答案中复制
…~
技巧。结果是

    text variable1 variable2 variable3 variable4    date Category_1 Category_2 Category_3 Subcategory_1 Subcategory_2 Subcategory_3
1: aaaaa        v1         N     LEASE         Y 2014-01         NA         c2         c3            NA           s22           s31
2: aaaaa        v1         N    RETAIL         Y 2014-01         c1         NA         NA           s11            NA            NA
3: bbbbb        v2         N     LEASE         Y 2014-01         c1         NA         NA           s12            NA            NA
4: ccccc        v1         N     LEASE         Y 2014-01         c2         NA         NA           s21            NA            NA
5: ddddd        v1         N     LEASE         Y 2014-01         NA         c3         NA            NA           s31            NA
6: ddddd        v1         N    RETAIL         Y 2014-01         c2         NA         NA           s21            NA            NA
7: eeeee        v1         N    RETAIL         Y 2014-01         c1         NA         NA           s11            NA            NA
8: fffff        v2         U    RETAIL         Y 2014-01         c2         NA         NA           s21            NA            NA

使用
dplyr
tidyr
的替代方案:

newdf <- df %>% gather(variable, value, product.category, sub.category) %>%
  group_by(ID, variable) %>%
  mutate(variable2 = paste0(variable, seq_along(value))) %>%
  ungroup() %>%
  select(-variable) %>%
  spread(variable2 , value)

在第二个示例数据集上也可以这样做:

newdat <- dat %>% gather(variable, value, Category, Subcategory) %>%
  group_by(text, variable) %>%
  mutate(var2 = paste0(variable, seq_along(value))) %>%
  ungroup() %>%
  select(-variable) %>%
  spread(var2 , value)

多谢各位!非常详细,可以理解:)嗨,Pierre,我试过你的代码,它给我的错误是“错误:未知列‘变量’”,这是我的代码“m3%group_by(文本,变量)%%>%mutate(variable2=paste0(变量,seq_沿(值))”,谢谢你做了一些修改,现在上面的问题似乎没问题了。。。但我得到了一个错误“错误:无法分配大小为5.6GB的向量”,这很奇怪,因为它不应该这么大……我尝试了一些子集,它生成了输出。。。。但有些奇怪的是,对于一些记录,它甚至有100个类别,但是1-99个类别都是空白的,你知道为什么我得到了错误的结果吗?如果没有实际的数据,很难确定什么是错误的。你能发布有代表性的示例吗?嗨,弗兰克,当我尝试你的代码时,它给我的错误是:“Error:value.var(product.categorysub.category)在输入中找不到”或“Error in.subset2(x,I,exact=exact):下标超出范围”这是我的代码,请告诉我应该如何修改它:“setDT(output)output[,obsno:=1.N,by=text]res-Hm,我不确定它为什么会失败。你可以在数据的较小子集上尝试它,比如
output2我只选择了10行作为output1并尝试了这个,但仍然不起作用……我将用新的细节更新我的问题……请看一下。谢谢Frank,我更新了新的表格式(我厌倦了编写代码,但不起作用的那个)在问题中…请看一看。Thanks@KarlTian我已经为您发布的新案例添加了代码。它似乎有效。@KarlTian看到更新的答案,现在它还包括第二个(新)案例的解决方案datasethanks Jaap:)将尝试我的Jaap,@Jaap,我尝试了你的,它是有效的……但我希望结果有所不同:对于第1行和第5行,类别1,2,3是否可能类似于
row1:c2,c3,na
row1:c2,c3,na
,这意味着无论非空值类别的顺序如何,都将它们放在'N'之前A'?Thanks@KarlTian我不完全确定您的意思,但您可以使用例如
arrange(Category1,Category2,Category3)
更改数据帧中观察值的顺序。这将首先通过
Category1
newdat进行排序,然后通过
Category2
,最后通过
Category3
DT2[, obsno := 1:.N, by=text]
dcast(DT2, ...~obsno, value.var=c("Category", "Subcategory"))
    text variable1 variable2 variable3 variable4    date Category_1 Category_2 Category_3 Subcategory_1 Subcategory_2 Subcategory_3
1: aaaaa        v1         N     LEASE         Y 2014-01         NA         c2         c3            NA           s22           s31
2: aaaaa        v1         N    RETAIL         Y 2014-01         c1         NA         NA           s11            NA            NA
3: bbbbb        v2         N     LEASE         Y 2014-01         c1         NA         NA           s12            NA            NA
4: ccccc        v1         N     LEASE         Y 2014-01         c2         NA         NA           s21            NA            NA
5: ddddd        v1         N     LEASE         Y 2014-01         NA         c3         NA            NA           s31            NA
6: ddddd        v1         N    RETAIL         Y 2014-01         c2         NA         NA           s21            NA            NA
7: eeeee        v1         N    RETAIL         Y 2014-01         c1         NA         NA           s11            NA            NA
8: fffff        v2         U    RETAIL         Y 2014-01         c2         NA         NA           s21            NA            NA
newdf <- df %>% gather(variable, value, product.category, sub.category) %>%
  group_by(ID, variable) %>%
  mutate(variable2 = paste0(variable, seq_along(value))) %>%
  ungroup() %>%
  select(-variable) %>%
  spread(variable2 , value)
> newdf
Source: local data frame [4 x 9]

     ID gender    age product.category1 product.category2 product.category3 sub.category1 sub.category2 sub.category3
  (int) (fctr) (fctr)             (chr)             (chr)             (chr)         (chr)         (chr)         (chr)
1     1      M  young              food           kitchen              food       chicken        napkin         steak
2     2      F    mid        electronic                NA                NA         phone            NA            NA
3     3      M    old             cloth           kitchen                NA         shirt          bowl            NA
4     4      F  young              alch                NA                NA          beer            NA            NA
newdat <- dat %>% gather(variable, value, Category, Subcategory) %>%
  group_by(text, variable) %>%
  mutate(var2 = paste0(variable, seq_along(value))) %>%
  ungroup() %>%
  select(-variable) %>%
  spread(var2 , value)
> newdat
Source: local data frame [8 x 12]

    text variable1 variable2 variable3 variable4    date Category1 Category2 Category3 Subcategory1 Subcategory2 Subcategory3
  (fctr)    (fctr)    (fctr)    (fctr)    (fctr)  (fctr)     (chr)     (chr)     (chr)        (chr)        (chr)        (chr)
1  aaaaa        v1         N     LEASE         Y 2014-01        NA        c2        c3           NA          s22          s31
2  aaaaa        v1         N    RETAIL         Y 2014-01        c1        NA        NA          s11           NA           NA
3  bbbbb        v2         N     LEASE         Y 2014-01        c1        NA        NA          s12           NA           NA
4  ccccc        v1         N     LEASE         Y 2014-01        c2        NA        NA          s21           NA           NA
5  ddddd        v1         N     LEASE         Y 2014-01        NA        c3        NA           NA          s31           NA
6  ddddd        v1         N    RETAIL         Y 2014-01        c2        NA        NA          s21           NA           NA
7  eeeee        v1         N    RETAIL         Y 2014-01        c1        NA        NA          s11           NA           NA
8  fffff        v2         U    RETAIL         Y 2014-01        c2        NA        NA          s21           NA           NA