我相信 SQL 可能是更好的地方,但如果您想知道如何在 R 中执行此操作,我假设您已经将相关数据下载到 dat。
(在所有三个示例中,order/arrange 的使用仅用于演示,在生产中不需要。)
基础 R
newdat <- data.frame(Quantity=15L, Name="Dany", Unit="L", Cost=2)
newlines <- aggregate(dat$Line, list(Product=dat$Product), FUN=function(z) max(z) + 10000)
names(newlines)[2] <- "Line"
newlines
# Product Line
# 1 Antonio 30000
# 2 Pepe 40000
# 3 Vanesa 50000
out <- rbind(dat, merge(newlines, newdat, by = NULL))
out <- out[order(out$Product, out$Line),]
out
# Product Line Name Quantity Unit Cost
# 4 Antonio 10000 Naiara 4 KG 8.0
# 5 Antonio 20000 Toni 7 KG 3.0
# 10 Antonio 30000 Dany 15 L 2.0
# 1 Pepe 10000 Lucia 4 UD 8.0
# 2 Pepe 20000 Santiago 7 UD 5.5
# 3 Pepe 30000 Mariangeles 10 KG 6.0
# 11 Pepe 40000 Dany 15 L 2.0
# 6 Vanesa 10000 Lucia 4 UD 8.0
# 7 Vanesa 20000 Santiago 7 KG 8.0
# 8 Vanesa 30000 Toni 10 KG 3.0
# 9 Vanesa 40000 Gines 4 KG 8.0
# 12 Vanesa 50000 Dany 15 L 2.0
tidyverse
library(dplyr)
# library(tidyr) # crossing
# newdat from above
dat %>%
group_by(Product) %>%
summarize(Line = max(Line) + 10000) %>%
tidyr::crossing(., newdat) %>%
bind_rows(dat) %>%
arrange(Product, Line)
# # A tibble: 12 x 6
# Product Line Quantity Name Unit Cost
# <chr> <dbl> <int> <chr> <chr> <dbl>
# 1 Antonio 10000 4 Naiara KG 8
# 2 Antonio 20000 7 Toni KG 3
# 3 Antonio 30000 15 Dany L 2
# 4 Pepe 10000 4 Lucia UD 8
# 5 Pepe 20000 7 Santiago UD 5.5
# 6 Pepe 30000 10 Mariangeles KG 6
# 7 Pepe 40000 15 Dany L 2
# 8 Vanesa 10000 4 Lucia UD 8
# 9 Vanesa 20000 7 Santiago KG 8
# 10 Vanesa 30000 10 Toni KG 3
# 11 Vanesa 40000 4 Gines KG 8
# 12 Vanesa 50000 15 Dany L 2
数据表
library(data.table)
datDT <- as.data.table(dat)
newdatDT <- as.data.table(newdat)
newlinesDT <- datDT[, .(Line = max(Line) + 10000), by = .(Product)]
rbindlist(list(
datDT,
base::merge.data.frame(newlinesDT, newdat, by = NULL)
), use.names = TRUE)[ order(Product,Line),]
# Product Line Name Quantity Unit Cost
# <char> <num> <char> <int> <char> <num>
# 1: Antonio 10000 Naiara 4 KG 8.0
# 2: Antonio 20000 Toni 7 KG 3.0
# 3: Antonio 30000 Dany 15 L 2.0
# 4: Pepe 10000 Lucia 4 UD 8.0
# 5: Pepe 20000 Santiago 7 UD 5.5
# 6: Pepe 30000 Mariangeles 10 KG 6.0
# 7: Pepe 40000 Dany 15 L 2.0
# 8: Vanesa 10000 Lucia 4 UD 8.0
# 9: Vanesa 20000 Santiago 7 KG 8.0
# 10: Vanesa 30000 Toni 10 KG 3.0
# 11: Vanesa 40000 Gines 4 KG 8.0
# 12: Vanesa 50000 Dany 15 L 2.0
我不知道如何让data.table:::merge.data.table 允许在没有连接键的情况下进行笛卡尔连接,所以我在这里强制使用base-case。作为另一种选择,我可以在两个框架中添加一个虚拟的单值列,然后加入该列。