将数据从长格式转换为宽格式

3

示例

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 列中的 articulo 并不合理。 - akrun
4个回答

5

你可以在这里使用简单的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创建indx的方式。 - akrun
它返回数值,并且只识别第一个项目。 - Saugandh Datta
因此,您需要提供一个可重现的示例,因为它在您的数据上有效。 - David Arenburg

3
您可以使用tidyr中的spread
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        

错误:行标识符重复。 - Saugandh Datta
@SaugandthData 根据提供的示例,我没有收到任何错误。由于存在重复项,您可能需要为原始数据集创建一个序列变量。您可以使用一个小示例更新帖子以获得错误信息。 - akrun
检查 %>% 按 customer_code 分组 %>% 展开(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、...)存在重复标识符。 - Saugandh Datta
@SaugandhDatta 我已经说了错误的原因。如果您可以更新您的帖子并提供一个能够重现该错误的小例子,我可以进行测试。 - akrun
文章代码 客户代码 子行业描述 子类别描述 9014 8.92E+12 杂货 调味品、意大利面(番茄酱和调味汁) 9014 8.92E+12 杂货 调味品、意大利面(番茄酱和调味汁) 9014 8.92E+12 杂货 商品 9014 3.25E+12 杂货 商品 9014 3.25E+12 杂货 调味品、意大利面(番茄酱和调味汁) 9014 3.25E+12 杂货 调味品、意大利面(番茄酱和调味汁) - Saugandh Datta
显示剩余2条评论

2

您可以尝试使用函数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] <- 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>

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

错误:行有重复标识符。 - Saugandh Datta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接