我想根据列中的值创建多个数据帧。
样本数据
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进行子集化。只是想知道是否有任何方法可以做到这一点?
答案 0 :(得分:7)
您可以创建数据框列表,然后使用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
答案 1 :(得分:4)
使用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])
答案 2 :(得分:3)
假设您的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
答案 3 :(得分:2)
您可以使用dplyr
创建Base
列,但为了清楚起见,这还没有创建不同的data.frames(如您的问题所示)。
require(dplyr)
df <- df %.% group_by(ID) %.% mutate(Base = first(Amount))
答案 4 :(得分:1)
或使用dplyr
:
library(dplyr)
df1 <- df %>%
arrange(ID, Amount) %>%
group_by(ID) %>%
mutate(Base = Amount[1])