使用R基于条件定义列表

时间:2016-01-08 07:36:17

标签: r

我有数据存储在数据框中

CST   M     QS
501 1204315 1
501 1204324 1
501 6041541 2
501 7508226 1
501 7509677 1
501 7514622 1
503 7511601 2
507 6961200 2
507 7514100 2
507 7522029 1
509 7512374 1
509 7516799 2
511 419110  0.5
511 6000832 5
511 6960800 3.33
511 7010000 2
511 7508229 2.5
511 7508307 2
511 7515126 2

现在,我想基于CST更改此数据,不同的M必须存储在不同的列中。这些列应该是动态的,这样CST只能有1 M或者可以是10或20或无限,因此必须使用M1,M2,M3等生成许多列。必须使用基于sum(M)

的值的总和来显示QS

示例输出如下

cst M1      M2      M3      M4      M5      M6      M7      Total
501 1204315 1204324 6041541 7508226 7509677 7514622         7
503 7511601                                                 2
507 6961200 7514100 7522029                                 5
509 7512374 7516799                                         3
511 419110  6000832 6960800 7010000 7508229 7508307 7515126 17.33

我使用了transpose(),它只是将行转换为列。但这不会解析为我想要的预期输出。

我已尝试将data.table函数用作dt[,sum(QS),by="CST"],但无法在不同的列中显示M及其。

提前致谢。

1 个答案:

答案 0 :(得分:3)

我们可以使用data.table。我们将'data.frame'转换为'data.table'(setDT(df1)),按'CST'分组,我们得到“QS”的行序列(1:.N)和sum “,分配(:=)输出以创建两列(”N“,”总计“)。然后,我们使用dcastlong转换为wide格式。

library(data.table)
setDT(df1)[, c("N", "Total") := list(paste0("M", 1:.N), sum(QS)), CST]
dcast(df1, CST+Total~N, value.var='M')
#   CST Total      M1      M2      M3      M4      M5      M6      M7
#1: 501  7.00 1204315 1204324 6041541 7508226 7509677 7514622      NA
#2: 503  2.00 7511601      NA      NA      NA      NA      NA      NA
#3: 507  5.00 6961200 7514100 7522029      NA      NA      NA      NA
#4: 509  3.00 7512374 7516799      NA      NA      NA      NA      NA
#5: 511 17.33  419110 6000832 6960800 7010000 7508229 7508307 7515126

或者我们使用与dplyr/tidyr

相同的方法
library(dplyr)
library(tidyr)
df1 %>%
  group_by(CST) %>%
  mutate(Total=sum(QS), N=row_number()) %>% 
  select(-QS) %>%
  spread(N, M)

更新

如果我们需要订单中的列,我们可以将“N”转换为factor并指定levels

 setDT(df2)[,  c("N", "Total") := list(paste0("M", 1:.N), sum(QS)), CST]
 df2[, N:= factor(N, levels=unique(N))]
 dcast(df2, CST+Total~N, value.var="M")

数据

 df2 <- structure(list(CST = c(501L, 501L, 501L, 501L, 501L, 
 501L, 501L, 
 501L, 501L, 501L, 501L, 501L, 503L, 507L, 507L, 507L, 509L, 509L, 
 511L, 511L, 511L, 511L, 511L, 511L, 511L), M = c(1204315L, 1204324L, 
 6041541L, 7508226L, 7509677L, 7434399L, 7843392L, 7834393L, 8343999L, 
 3439242L, 3434323L, 7514622L, 7511601L, 6961200L, 7514100L, 7522029L, 
 7512374L, 7516799L, 419110L, 6000832L, 6960800L, 7010000L, 7508229L, 
 7508307L, 7515126L), QS = c(1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 
 1, 2, 2, 2, 1, 1, 2, 0.5, 5, 3.33, 2, 2.5, 2, 2)),
 .Names = c("CST", 
 "M", "QS"), class = "data.frame", row.names = c(NA, -25L))