如何将因子变量的不相等数据帧列表转换为新的数据帧

时间:2017-10-11 21:49:05

标签: r list dataframe apply plyr

我的列表(l)包含不同长度的不同数据帧。
x1,x2和x3是不同产品变量的值。
y是从1到15的因子变量。

我努力通过正确但不相等的分布式因子变量y来匹配或加入这些数据帧。

.xaml

经常推荐,但在这种情况下不起作用是以下行:

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)

我的预期输出是ONE,新数据框或表格如下:

do.call(rbind.fill, l)

2 个答案:

答案 0 :(得分:1)

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)

答案 1 :(得分:0)

可能有更好的方法可以做到这一点,但基本上你可以使用reduce将所有3个数据帧合并在一起。然后,我们可以创建第二个数据帧,其合并数据帧中缺少y的值,并且为1:15,并为缺少的值的数量重复x1,x2,x3。然后只是rbind和sort。

> 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)