我的列表(l)包含不同长度的不同数据帧。
x1、x2 和 x3 是不同乘积变量的值。
y 是从 1 到 15 的因子变量。
我纠结如何通过正确但不相等的分布因子变量 y 匹配或连接这些数据框。
df1 <- data.frame(x1=c(100,10,20,70,30), y =as.factor(c(1,2,3,11,15)))
df2 <- data.frame(x2=c(11,22,33,44,55,66,77,88,99), y =as.factor(c(1,2,3,4,5,7,8,11,12)))
df3 <- data.frame(x3=c(11,12,13,14,15,16,17,18,19,20), y =as.factor(c(1,2,3,4,5,11,12,13,14,15)))
l <- list(df1,df2,df3)
通常推荐,但在这种情况下不起作用的是以下行:
do.call(rbind.fill, l)
我的预期输出是一个,新的数据框或表,如下所示:
x1 x2 x3
1 100 11 11
2 10 22 12
3 20 33 13
4 NA 44 14
5 NA 55 15
6 NA NA NA
7 NA 66 NA
8 NA 77 NA
9 NA NA NA
10 NA NA NA
11 70 88 16
12 NA 99 17
13 NA NA 18
14 NA NA 19
15 30 NA 20
library(dplyr)
qqq <- full_join(df1, df2, by='y')
%>% full_join(df3, by = 'y')
%>% mutate(y = as.numeric(as.character(y)))
y_seq <- data.frame(y = 1:15)
qqq <- full_join(qqq, y_seq, by='y') %>% arrange(y)
rownames(qqq) <- qqq$y
qqq <- select(qqq, -y)
可能有更好的方法可以做到这一点,但基本上您可以使用reduce将所有3个数据帧合并在一起。然后,我们可以创建第二个数据帧,其中包含合并数据帧中缺少的 y 值和 1:15,并代表 x1、x2、x3 作为缺失的值的数量。然后只需重新绑定和排序。
> df = Reduce(function(...) merge(..., all = T), l)
> df
y x1 x2 x3
1 1 100 11 11
2 2 10 22 12
3 3 20 33 13
4 11 70 88 16
5 15 30 NA 20
6 4 NA 44 14
7 5 NA 55 15
8 7 NA 66 NA
9 8 NA 77 NA
10 12 NA 99 17
11 13 NA NA 18
12 14 NA NA 19
df$y = as.numeric(levels(df$y))
df2 = data.frame(c(which(!1:15 %in% df$y)), c(rep(NA, length(which(!1:15 %in% df$y)))), c(rep(NA, length(which(!1:15 %in% df$y)))),c(rep(NA, length(which(!1:15 %in% df$y)))))
colnames(df2) = colnames(df)
df = rbind.data.frame(df, df2)
df = df[order(df$y),]
> df
y x1 x2 x3
1 1 100 11 11
2 2 10 22 12
3 3 20 33 13
6 4 NA 44 14
7 5 NA 55 15
13 6 NA NA NA
8 7 NA 66 NA
9 8 NA 77 NA
14 9 NA NA NA
15 10 NA NA NA
4 11 70 88 16
10 12 NA 99 17
11 13 NA NA 18
12 14 NA NA 19
5 15 30 NA 20
编辑
大卫填充额外行的方式要好得多,所以我要偷它。
df1 <- data.frame(x1=c(100,10,20,70,30), y =as.factor(c(1,2,3,11,15)))
df2 <- data.frame(x2=c(11,22,33,44,55,66,77,88,99), y =as.factor(c(1,2,3,4,5,7,8,11,12)))
df3 <- data.frame(x3=c(11,12,13,14,15,16,17,18,19,20), y =as.factor(c(1,2,3,4,5,11,12,13,14,15)))
l <- list(df1,df2,df3)
df = Reduce(function(...) merge(..., all = T), l)
df$y = as.numeric(levels(df$y))
df2 = data.frame(y = 1:15)
df = merge(df, df2, on = "y", all = TRUE)