我有一个带有分组行和列的数据框,并希望根据另一个数据框中包含的信息多次添加整个行组。在示例数据中,我通过三次复制id为1(1990年1月1日)的行显示了我希望得到的最终输出。变量“dups”表示该组应被复制的次数。
以下是dput示例:
> dput(df)
structure(list(date = c("01-jan-90", "01-jan-90", "01-jan-90",
"01-jan-90", "01-jan-90", "02-jan-90", "02-jan-90", "02-jan-90",
"02-jan-90", "02-jan-90"), rdate = c("08-jan-90", "15-jan-90",
"01-jan-90", "22-jan-90", "29-jan-90", "09-jan-90", "16-jan-90",
"02-jan-90", "23-jan-90", "30-jan-90"), id = c(1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L)), datalabel = "", time.stamp = "30 Dec 2013 16:39", .Names = c("date",
"rdate", "id"), formats = c("%9s", "%9s", "%8.0g"), types = c(9L,
9L, 251L), val.labels = c("", "", ""), var.labels = c("", "",
""), row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9",
"10"), version = 12L, class = "data.frame")
以下是有关日期和复制次数的信息:
date dups id
01-jan-90 3 1
02-jan-90 2 2
1990年1月1日ID 1的输出如下:
date rdate id newid
1 01-jan-90 08-jan-90 1 1
2 01-jan-90 15-jan-90 1 1
3 01-jan-90 01-jan-90 1 1
4 01-jan-90 22-jan-90 1 1
5 01-jan-90 29-jan-90 1 1
6 01-jan-90 08-jan-90 1 2
7 01-jan-90 15-jan-90 1 2
8 01-jan-90 01-jan-90 1 2
9 01-jan-90 22-jan-90 1 2
10 01-jan-90 29-jan-90 1 2
11 01-jan-90 08-jan-90 1 3
12 01-jan-90 15-jan-90 1 3
13 01-jan-90 01-jan-90 1 3
14 01-jan-90 22-jan-90 1 3
15 01-jan-90 29-jan-90 1 3
答案 0 :(得分:1)
df2 <- read.table(textConnection("date dups id
01-jan-90 3 1
02-jan-90 2 2"), sep=" ", header=T)
dup <- function(df, date, num) {
i <- which(df$date==date)
cbind(df[rep(i,num),], newid=rep(1:num, each=length(i)))
}
df3 <- data.frame()
for (x in 1:nrow(df2)) {
df3 <- rbind(df3, dup(df, df2$date[x], df2$dups[x]))
}
df3
# date rdate id newid
# 1 01-jan-90 08-jan-90 1 1
# 2 01-jan-90 15-jan-90 1 1
# 3 01-jan-90 01-jan-90 1 1
# 4 01-jan-90 22-jan-90 1 1
# 5 01-jan-90 29-jan-90 1 1
# 1.1 01-jan-90 08-jan-90 1 2
# 2.1 01-jan-90 15-jan-90 1 2
# 3.1 01-jan-90 01-jan-90 1 2
# 4.1 01-jan-90 22-jan-90 1 2
# 5.1 01-jan-90 29-jan-90 1 2
# 1.2 01-jan-90 08-jan-90 1 3
# 2.2 01-jan-90 15-jan-90 1 3
# 3.2 01-jan-90 01-jan-90 1 3
# 4.2 01-jan-90 22-jan-90 1 3
# 5.2 01-jan-90 29-jan-90 1 3
# 6 02-jan-90 09-jan-90 2 1
# 7 02-jan-90 16-jan-90 2 1
# 8 02-jan-90 02-jan-90 2 1
# 9 02-jan-90 23-jan-90 2 1
# 10 02-jan-90 30-jan-90 2 1
# 6.1 02-jan-90 09-jan-90 2 2
# 7.1 02-jan-90 16-jan-90 2 2
# 8.1 02-jan-90 02-jan-90 2 2
# 9.1 02-jan-90 23-jan-90 2 2
# 10.1 02-jan-90 30-jan-90 2 2
答案 1 :(得分:1)
使用merge
:
首先,我们假设您的“复制器”data.frame
被称为“mydf”。其次,merge
,创建sequence
列的dups
,“展开”您的行,并重新绑定新ID。
A <- merge(df, mydf)
newID <- sequence(A$dups)
out <- cbind(A[rep(rownames(A), A$dups), c("date", "id", "rdate")], newID)
head(out)
# date id rdate newID
# 1 01-jan-90 1 08-jan-90 1
# 1.1 01-jan-90 1 08-jan-90 2
# 1.2 01-jan-90 1 08-jan-90 3
# 2 01-jan-90 1 15-jan-90 1
# 2.1 01-jan-90 1 15-jan-90 2
# 2.2 01-jan-90 1 15-jan-90 3
订单与您的示例输出不同,但使用order
很容易解决,如下所示:
outordered <- out[with(out, do.call(order, list(date, id, newID))), ]
head(outordered, 10)
# date id rdate newID
# 1 01-jan-90 1 08-jan-90 1
# 2 01-jan-90 1 15-jan-90 1
# 3 01-jan-90 1 01-jan-90 1
# 4 01-jan-90 1 22-jan-90 1
# 5 01-jan-90 1 29-jan-90 1
# 1.1 01-jan-90 1 08-jan-90 2
# 2.1 01-jan-90 1 15-jan-90 2
# 3.1 01-jan-90 1 01-jan-90 2
# 4.1 01-jan-90 1 22-jan-90 2
# 5.1 01-jan-90 1 29-jan-90 2
tail(outordered)
# date id rdate newID
# 10 02-jan-90 2 30-jan-90 1
# 6.1 02-jan-90 2 09-jan-90 2
# 7.1 02-jan-90 2 16-jan-90 2
# 8.1 02-jan-90 2 02-jan-90 2
# 9.1 02-jan-90 2 23-jan-90 2
# 10.1 02-jan-90 2 30-jan-90 2
答案 2 :(得分:1)
# Create the data.frame with the number of duplications
# assuming it is unique on date/id
id <- unique(df[, c("date", "id")])
id$dups <- c(3, 2)
library(plyr)
# Use ddply to cycle through the id df, and lapply to
# duplicate the df
ddply(id, c("date", "id"),
function(df.sub) {
if(nrow(df.sub) != 1L) stop("Logic error") # id df shoudl be unique on date/id
df.to.rep <- subset(df, date==df.sub$date & id==df.sub$id)
df.rep <- lapply(1:df.sub$dups, function(newid) transform(df.to.rep, newid=newid))
do.call(rbind, df.rep)
}
)
# date rdate id newid
# 1 01-jan-90 08-jan-90 1 1
# 2 01-jan-90 15-jan-90 1 1
# 3 01-jan-90 01-jan-90 1 1
# 4 01-jan-90 22-jan-90 1 1
# 5 01-jan-90 29-jan-90 1 1
# 6 01-jan-90 08-jan-90 1 2
# 7 01-jan-90 15-jan-90 1 2
# 8 01-jan-90 01-jan-90 1 2
# 9 01-jan-90 22-jan-90 1 2
# 10 01-jan-90 29-jan-90 1 2
# 11 01-jan-90 08-jan-90 1 3
# 12 01-jan-90 15-jan-90 1 3
# 13 01-jan-90 01-jan-90 1 3
# 14 01-jan-90 22-jan-90 1 3
# 15 01-jan-90 29-jan-90 1 3
# 16 02-jan-90 09-jan-90 2 1
# 17 02-jan-90 16-jan-90 2 1
# 18 02-jan-90 02-jan-90 2 1
# 19 02-jan-90 23-jan-90 2 1
# 20 02-jan-90 30-jan-90 2 1
# 21 02-jan-90 09-jan-90 2 2
# 22 02-jan-90 16-jan-90 2 2
# 23 02-jan-90 02-jan-90 2 2
# 24 02-jan-90 23-jan-90 2 2
# 25 02-jan-90 30-jan-90 2 2