我想根据列中的值创建多个数据帧。
sample data
df Index Product ID Amount 200 Prod1 01 100 201 Prod1 01 150 202 Prod1 01 123 203 Prod1 01 123 204 Prod1 02 110 205 Prod1 02 175 206 Prod1 02 190 207 Prod2 03 120 208 Prod2 03 135 209 Prod2 03 150
我想为每个ID添加一列作为Base。 Base的值是每个ID中的第一个金额值。
>df1
Index Product ID Amount Base
200 Prod1 01 100 100
201 Prod1 01 150 100
202 Prod1 01 123 100
203 Prod1 01 123 100
204 Prod1 02 110 110
205 Prod1 02 175 110
206 Prod1 02 190 110
207 Prod2 03 120 120
208 Prod2 03 135 120
209 Prod2 03 150 120
我想首先通过ID对df进行子集化。只是想知道是否有任何方法可以做到这一点?
假设你的data.frame被称为dat
,这是一个data.table
解决方案:
require(data.table)
setDT(dat)[, Base := Amount[1L], by=ID]
# Index Product ID Amount Base
# 1: 200 Prod1 1 100 100
# 2: 201 Prod1 1 150 100
# 3: 202 Prod1 1 123 100
# 4: 203 Prod1 1 123 100
# 5: 204 Prod1 2 110 110
# 6: 205 Prod1 2 175 110
# 7: 206 Prod1 2 190 110
# 8: 207 Prod2 3 120 120
# 9: 208 Prod2 3 135 120
# 10: 209 Prod2 3 150 120
您可以创建数据框列表,然后使用list2env
将它们嵌入到您想要的任何环境中
SubData <- lapply(unique(df$ID), function(x) cbind(df[df$ID == x, ], Base = df$Amount[df$ID == x][1]))
# [[1]]
# Index Product ID Amount Base
# 1 200 Prod1 1 100 100
# 2 201 Prod1 1 150 100
# 3 202 Prod1 1 123 100
# 4 203 Prod1 1 123 100
#
# [[2]]
# Index Product ID Amount Base
# 5 204 Prod1 2 110 110
# 6 205 Prod1 2 175 110
# 7 206 Prod1 2 190 110
#
# [[3]]
# Index Product ID Amount Base
# 8 207 Prod2 3 120 120
# 9 208 Prod2 3 135 120
# 10 209 Prod2 3 150 120
现在为您的数据框提供您想要的任何名称,并使用list2env
在环境中创建它们
names(SubData) <- c("df1", "df2", "df3")
list2env(SubData, envir = .GlobalEnv)
现在,您可以在全局环境中拥有这些数据集,例如
df1
## Index Product ID Amount Base
## 1 200 Prod1 1 100 100
## 2 201 Prod1 1 150 100
## 3 202 Prod1 1 123 100
## 4 203 Prod1 1 123 100
使用ave
:
dat$Base <- ave(dat$Amount,dat$ID,FUN=min)
# Index Product ID Amount Base
# 1 200 Prod1 1 100 100
# 2 201 Prod1 1 150 100
# 3 202 Prod1 1 123 100
# 4 203 Prod1 1 123 100
# 5 204 Prod1 2 110 110
# 6 205 Prod1 2 175 110
# 7 206 Prod1 2 190 110
# 8 207 Prod2 3 120 120
# 9 208 Prod2 3 135 120
# 10 209 Prod2 3 150 120
如果你想要第一个值和最小值:
dat$Base <- ave(dat$Amount,dat$ID,FUN=function(x)x[1])
您可以使用dplyr
创建Base
列,但为了清楚,这还没有创建不同的data.frames(如您的问题中所示)。
require(dplyr)
df <- df %.% group_by(ID) %.% mutate(Base = first(Amount))
或者使用dplyr
:
library(dplyr)
df1 <- df %>%
arrange(ID, Amount) %>%
group_by(ID) %>%
mutate(Base = Amount[1])