我正在尝试扩展数据帧的一部分中包含的系列,并重复其余列中的值以填充新行。我有一个需要使用的分组变量,然后重新组合以再次拥有单个数据帧。下面是我的意思的一个例子,以及我将如何逐段地做到这一点:
df <- data.frame("group" = c(rep("A",3),rep("B",3)), val=rep(c(1,3,5),2))
values <- data.frame(val=seq(1:5))
df2.a <- df[df$group=="A",]
df3.a <- right_join(df2.a, values, "val")
df3.a$group <- "A"
df2.b <- df[df$group=="B",]
df3.b <- right_join(df2.b, values, "val")
df3.b$group <- "B"
df4 <- rbind(df3.a, df3.b)
在这里,df4
是我想要的输出。
但我相信使用dplyr
或其他一些拆分-应用-组合方法可以更有效率,尽管我显然错过了一些东西。
从概念上讲,这对我来说是有意义的:
df.interp <- df %>%
group_by(group) %>%
full_join(x=., y=values, by="val") %>%
fill(group)
虽然我无法完成这里的最后一行,因为我无法编辑分组变量。但是如果我ungroup
,那么我不再一次对一个组进行操作,并且我用错误的值填充新行(没有足够的行(。
我确定我在这里错过了一些简单的东西...这是什么?
library(dplyr)
library(tidyr)
df %>%
group_by(group) %>%
complete(val = min(val):max(val))
# # A tibble: 10 x 2
# # Groups: group [2]
# group val
# <fct> <dbl>
# 1 A 1
# 2 A 2
# 3 A 3
# 4 A 4
# 5 A 5
# 6 B 1
# 7 B 2
# 8 B 3
# 9 B 4
# 10 B 5
添加一个data.table
选项。
定义帮助程序函数
f <- function(x) {
tmp <- range(x)
tmp[1]:tmp[2]
}
按组应用f
library(data.table)
out <- setDT(df)[, .(val = f(val)), by=group]
out
# group val
# 1: A 1
# 2: A 2
# 3: A 3
# 4: A 4
# 5: A 5
# 6: B 1
# 7: B 2
# 8: B 3
# 9: B 4
#10: B 5
不确定实际数据如何,但是否存在特定组最大值与values$val
最大值不同的情况?因此,例如,在这种情况下,如果df
中没有第 3 行和 5 怎么办?我们还需要A
组直到 5 行吗?如果是这种情况,我们可以从values
数据帧完成我们的序列。
使用tidyr::crossing
tidyr::crossing(df %>% select(group), values)
# A tibble: 10 x 2
# group val
# <fct> <int>
# 1 A 1
# 2 A 2
# 3 A 3
# 4 A 4
# 5 A 5
# 6 B 1
# 7 B 2
# 8 B 3
# 9 B 4
#10 B 5
或者用complete
tidyr::complete(group, val = seq(min(values$val), max(values$val)))
data.table
中的CJ
轻松完成:
> setDT(df)
> df[CJ(group = group, val= values$val, unique = T), on = .(group, val)]
group val
1: A 1
2: A 2
3: A 3
4: A 4
5: A 5
6: B 1
7: B 2
8: B 3
9: B 4
10: B 5