【问题标题】:Reshape from long to wide format [duplicate]从长格式重塑为宽格式[重复]
【发布时间】:2015-08-04 05:55:39
【问题描述】:

例子

customer_code    items
1                sugar
1                salt       
2                sugar      
2                accessories
3                salt

期望的输出

customer_code   item   item2       item3
1              sugar   salt     
2              sugar             accessories
3                      salt

【问题讨论】:

  • des_subcat1 的预期输出中的 NA 值没有意义,因为客户 ID 3.12E+12des_subcat 列中有文章

标签: r reshape


【解决方案1】:

dplyr 尤其是tidyr 可以解决这类问题。这段代码可以解决问题。

require("tidyr")
require("dplyr")
df %>% group_by(customer_code) %>% spread(items, items) -> df_wide
#   customer_code accessories salt sugar
# 1             1          NA salt sugar
# 2             2 accessories   NA sugar
# 3             3          NA salt    NA

希望如有必要更改列名没有问题:

names(df_wide)[-1] <- paste0("item", 1:(ncol(df_wide)-1))
#   customer_code       item1 item2 item3
# 1             1          NA  salt sugar
# 2             2 accessories    NA sugar
# 3             3          NA  salt    NA

另外可能建议这种形式的输出(可能比较方便):

df  %>% mutate(present = T) %>% spread(items, present, fill = F)
#   customer_code accessories  salt sugar
# 1             1       FALSE  TRUE  TRUE
# 2             2        TRUE FALSE  TRUE
# 3             3       FALSE  TRUE FALSE

【讨论】:

  • 错误:行标识符重复
【解决方案2】:

你可以在这里做一个简单的dcast

library(reshape2)
dcast(df, customer_code ~ paste("items", items, sep = "_"), value.var = "items")
#   customer_code items_accessories items_salt items_sugar
# 1             1              <NA>       salt       sugar
# 2             2       accessories       <NA>       sugar
# 3             3              <NA>       salt        <NA>

或者更接近你想要的输出

library(data.table)
setDT(df)[, indx := paste0("items", .GRP), by = items]
dcast(df, customer_code ~ indx, value.var = "items")
#    customer_code items1 items2      items3
# 1:             1  sugar   salt          NA
# 2:             2  sugar     NA accessories
# 3:             3     NA   salt          NA

【讨论】:

  • 我喜欢你用.GRP创建索引的方式
  • 它返回数值并仅标识第一项
  • 因此您需要提供可重现的示例,因为它适用于您的数据
【解决方案3】:

你可以尝试使用函数reshape:

尽可能多地获取不同项目的列:

new_df <- reshape(df, idvar="customer_code", timevar="items", v.names="items", direction="wide")
new_df
#  customer_code items.sugar items.salt items.accessories
#1             1       sugar       salt              <NA>
#3             2       sugar       <NA>       accessories
#5             3        <NA>       salt              <NA>

之后您可以使用 colnames(new_df)[-1] &lt;- paste0("item", 1:(ncol(new_df)-1)) 更改列名

另一个选项,如果您想获得与唯一客户可以拥有的最大项目数一样多的列:

df_split <- split(df, df[, 1])
df_split <- lapply(df_split, reshape, idvar="customer_code", timevar="items", v.names="items", direction="wide")
max_item <- max(sapply(df_split, ncol))
df_split <- lapply(df_split, function(df){ 
                                 if(ncol(df) < max_item) df <- cbind(df, matrix(NA, ncol=max_item - ncol(df)))
                                 colnames(df)[-1] <- paste0("item", 1:(max_item-1))
                                 return(df)
                              })
new_df <- do.call("rbind", df_split)
new_df
#  customer_code item1       item2
#1             1 sugar        salt
#2             2 sugar accessories
#3             3  salt        <NA>

【讨论】:

    【解决方案4】:

    您可以使用 spread 中的 tidyr

    library(dplyr)
    library(tidyr)
      mutate(df1, var=factor(items, levels=unique(items), 
          labels=paste0('items', seq(n_distinct(items))))) %>% 
                spread(var, items, fill='')
    #  customer_code items1 items2      items3
    #1             1  sugar   salt            
    #2             2  sugar        accessories
    #3             3          salt        
    

    【讨论】:

    • 错误:行标识符重复
    • @SaugandthData 根据提供的示例,我没有收到任何错误。您可能需要为原始数据集创建一个序列变量,因为存在重复项。您可以使用给出错误的小示例更新帖子
    • 检查 %>% group_by(customer_code) %>% spread(des_subcat, des_subcat) -> df_wide 错误:行标识符重复(353、354、355、356、357、358、359、360 , 361, 362, 363), (111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121), (683, 684, 685, 686, 687, 688, 689, 690, 691 , 692, 693), (34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165 , 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726), (518, 519 , 520, 521, 522, 523, 524, 525, 526, 527, 528), (474, 475,
    • @SaugandhDatta 我已经说过错误的原因。如果您可以用一个重现错误的小示例更新您的帖子,我可以对其进行测试。
    • article_code customer_code des_subsettore des_subcat 9014 8.92E+12 GROCERY CONDIMENTI PRIMI (PELATI & SUGHI) 9014 8.92E+12 GROCERY CONDIMENTI PRIMI (PELATI & SUGHI) 9014 8.92E+12 GROCERY articlo 901 GROCERY 文章 9014 3.25E+12 GROCERY CONDIMENTI PRIMI (PELATI & SUGHI) 9014 3.25E+12 GROCERY CONDIMENTI PRIMI (PELATI & SUGHI)
    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    相关资源
    最近更新 更多