Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-旋转困难的数据帧_R_Dataframe_Tidyverse_Spread_Dcast - Fatal编程技术网

R-旋转困难的数据帧

R-旋转困难的数据帧,r,dataframe,tidyverse,spread,dcast,R,Dataframe,Tidyverse,Spread,Dcast,假设我有三个销售各种产品的销售代表的销售数据。困难的是,每个销售代表销售的产品组合不同,但数量也不一定相同: Bob销售产品A、B和C 迈克销售产品A、B、C和D Sara销售产品A、B和E RepName Product SalesDollarAmt SalesQty 1 Bob A 43 3 2 Mike A 14 5 3 Sara A

假设我有三个销售各种产品的销售代表的销售数据。困难的是,每个销售代表销售的产品组合不同,但数量也不一定相同:

Bob销售产品A、B和C

迈克销售产品A、B、C和D

Sara销售产品A、B和E

   RepName Product SalesDollarAmt SalesQty
 1     Bob       A             43        3
 2    Mike       A             14        5
 3    Sara       A             53        1
 4     Bob       B            100       35
 5    Mike       B            215       80
 6    Sara       B            310      105
 7     Bob       C              5        8
 8    Mike       C             10        3
 9    Mike       D            105       50
10    Sara       E             25       18
我想在产品上旋转它,结果如下所示:

  RepName Product.1 SalesDollarAmt.1 SalesQty.1 Product.2 SalesDollarAmt.2 SalesQty.2 Product.3 SalesDollarAmt.3 SalesQty.3 Product.4 SalesDollarAmt.4 SalesQty.4
1     Bob         A               43          3         B              100         35         C                5          8      <NA>                0          0
2    Mike         A               14          5         B              215         80         C               10          3         D              105         50
3    Sara         A               53          1         B              310        105         E               25         18      <NA>                0          0

通过组合使用
行号
聚集
排列
联合
,我们可以重塑数据。如果您愿意的话,您可以对列重新排序。在最后一行中,我们在调用
spread
时指定
convert=TRUE
。这是因为当我们将数据转换为长格式(使用
聚集
)时,列值将转换为字符。在调用
spread
时指定
convert=TRUE
(应该)可以将值返回到有用的形式

df %>%
  group_by(RepName) %>%
  mutate(product_count = row_number()) %>% # product "id" within RepName
  gather(variable, value, -RepName, -product_count) %>% # reshape to long
  unite(var_prod, variable, product_count) %>%
  spread(var_prod, value, convert = TRUE) # reshape to wide

  RepName Product_1 Product_2 Product_3 Product_4 SalesDollarAmt_1 SalesDollarAmt_2 SalesDollarAmt_3 SalesDollarAmt_4 SalesQty_1 SalesQty_2 SalesQty_3 SalesQty_4
1     Bob         A         B         C      <NA>               43              100                5             <NA>          3         35          8       <NA>
2    Mike         A         B         C         D               14              215               10              105          5         80          3         50
3    Sara         A         B         E      <NA>               53              310               25             <NA>          1        105         18       <NA>
df%>%
分组人(RepName)%>%
在RepName中更改(产品计数=行数())%>%#产品“id”
聚集(变量,值,-RepName,-product_count)%>%#将形状改为长形
单位(变量产品、变量、产品计数)%>%
排列(var_prod,value,convert=TRUE)#重塑为宽
RepName Product_1 Product_2 Product_3 Product_4 SalesDollArmat_1 SalesDollArmat_2 SalesDollArmat_3 SalesDollArmat_4 SalesQty_1 SalesQty_2 SalesQty_3 SalesQty_4
1 Bob A B C 43 100 5 3 35 8
2麦克A B C D 14 215 10 105 5 80 3 50
3 Sara A B E 53 310 25 1 105 18

这个问题被标记为
dcast
,因此我觉得有义务发布一个使用
dcast()的解决方案

data.table
版本的
dcast()。此外,
rowid()
函数用于分别填充每个
RepName
的列:

library(data.table)
cast(setDT(df), RepName ~ rowid(RepName), value.var = c("Product", "SalesDollarAmt", "SalesQty"))
编辑:改进的版本,列按要求的顺序排列 ,OP已披露,由于数据将由Excel宏进一步处理,因此需要进行重塑。通常,列的位置对于Excel公式至关重要

因此,下面的变体是对列进行重新排序,以便将属于一个产品的所有列分组在一起:

library(data.table)
# value columns
val <- c("Product", "SalesDollarAmt", "SalesQty")
# create vector of column names in the expected order
col_order <- setDT(df)[, .N, by = RepName][, CJ(seq_len(max(N)), val)][, paste(V2, V1, sep = "_")]
dcast(df, RepName ~ rowid(RepName), value.var = val)[
  #re-order columns in place, i.e., without copying
  , setcolorder(.SD, c("RepName", col_order))]

是否每个
RepName
Product
都只有一行?(例如,Bob对于产品A是否只有一行?)是的,这是正确的;这是一段时间内的销售数据,因此不会有重复。似乎您正在将数据从整洁的格式转换为不整洁的格式。请问原因是什么?有时有更好的解决方案来解决潜在问题。我需要将输出传递给其他人,他们使用一个破旧的Excel宏生成报告,这样对他来说效果更好;宏在各行中循环,并使用VLOOKUPs一次创建每个代表的报告。非常感谢!这太棒了。
   RepName Product_1 Product_2 Product_3 Product_4 SalesDollarAmt_1 SalesDollarAmt_2 SalesDollarAmt_3 SalesDollarAmt_4 SalesQty_1 SalesQty_2 SalesQty_3 SalesQty_4
1:     Bob         A         B         C        NA               43              100                5               NA          3         35          8         NA
2:    Mike         A         B         C         D               14              215               10              105          5         80          3         50
3:    Sara         A         B         E        NA               53              310               25               NA          1        105         18         NA
library(data.table)
# value columns
val <- c("Product", "SalesDollarAmt", "SalesQty")
# create vector of column names in the expected order
col_order <- setDT(df)[, .N, by = RepName][, CJ(seq_len(max(N)), val)][, paste(V2, V1, sep = "_")]
dcast(df, RepName ~ rowid(RepName), value.var = val)[
  #re-order columns in place, i.e., without copying
  , setcolorder(.SD, c("RepName", col_order))]
   RepName Product_1 SalesDollarAmt_1 SalesQty_1 Product_2 SalesDollarAmt_2 SalesQty_2 Product_3 SalesDollarAmt_3 SalesQty_3 Product_4 SalesDollarAmt_4 SalesQty_4
1:     Bob         A               43          3         B              100         35         C                5          8        NA               NA         NA
2:    Mike         A               14          5         B              215         80         C               10          3         D              105         50
3:    Sara         A               53          1         B              310        105         E               25         18        NA               NA         NA