R:合并表并用因子信息填充空单元格

时间:2015-04-23 03:01:35

标签: r dplyr

我有一个相对复杂的表合并/扩展问题。下面我添加了一个示例DATA和所需的RESULT表。我有4个因素(SITEDATESAMPLETAXA)和三个数字列(12,{{1} })。我需要让每个3SITEDATE拥有SAMPLE 1,2,100和150.通过这个过程我需要填写空因子具有适当信息的单元格,并用0表示填充数字列。

我为大型“示例”数据集道歉,但它们捕获了我的数据集的复杂性。我的完整数据集有点大,包括4 TAXA,15 SITE,12 DATE和167 SAMPLE。使用TAXA的解决方案是首选,但我肯定对其他选项持开放态度。在excel中这样做需要一个浣熊的年龄!提前谢谢。

dplyr

2 个答案:

答案 0 :(得分:2)

从您的数据开始:

dat <- structure(list(SITE = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
                          .Label = c("NSV", "SFP"), class = "factor"),
                      DATE = structure(c(4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
                          .Label = c("23-Oct-13", "27-Oct-13", "4-Jul-13", "8-Jul-13"
                                     ), class = "factor"),
                      SAMPLE = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("Pool", "Riffle"), class = "factor"),
                      TAXA = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 100L, 150L, 1L, 2L, 100L, 150L),
                      v1 = c(10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L),
                      v2 = c(10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L),
                      v3 = c(10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L)),
                 .Names = c("SITE", "DATE", "SAMPLE", "TAXA", "v1", "v2", "v3"),
                 class = "data.frame", row.names = c(NA, -20L))

一种技术,使用dplyr

library(dplyr)
eg <- do.call('expand.grid', lapply(dat[,1:4], unique))
result <- right_join(dat, eg, by=c('SITE', 'DATE', 'SAMPLE', 'TAXA')) %>%
    mutate(v1 = ifelse(is.na(v1), 0, v1),
           v2 = ifelse(is.na(v2), 0, v2),
           v3 = ifelse(is.na(v3), 0, v3)) %>%
    arrange(SITE, DATE, SAMPLE, TAXA)
head(result, n=8)
##   SITE      DATE SAMPLE TAXA v1 v2 v3
## 1  NSV 23-Oct-13   Pool    1 10 10 10
## 2  NSV 23-Oct-13   Pool    2 10 10 10
## 3  NSV 23-Oct-13   Pool  100  0  0  0
## 4  NSV 23-Oct-13   Pool  150  0  0  0
## 5  NSV 23-Oct-13 Riffle    1 10 10 10
## 6  NSV 23-Oct-13 Riffle    2 10 10 10
## 7  NSV 23-Oct-13 Riffle  100  0  0  0
## 8  NSV 23-Oct-13 Riffle  150  0  0  0

使用arrange只是为了安排它,就像你的结果一样,但数据是完整的。

<强> 修改

我意识到我在结果data.frame中有太多了。这是更正确的,基于@Frank的评论,更紧凑(arrange仍然是可选的):

dat %>% select(SITE, DATE, SAMPLE) %>% unique() %>%
    merge(y=list(TAXA=unique(dat$TAXA)), all.x=TRUE) %>%
    arrange(SITE, DATE, SAMPLE, TAXA)
##    SITE      DATE SAMPLE TAXA
## 1   NSV 23-Oct-13   Pool    1
## 2   NSV 23-Oct-13   Pool    2
## 3   NSV 23-Oct-13   Pool  100
## 4   NSV 23-Oct-13   Pool  150
## 5   NSV 23-Oct-13 Riffle    1
## 6   NSV 23-Oct-13 Riffle    2
## 7   NSV 23-Oct-13 Riffle  100
## 8   NSV 23-Oct-13 Riffle  150
## ...snip...

答案 1 :(得分:2)

这是一个非dplyr解决方案。我确信有更优雅的方式,但这里有一个基本的R方法。我调用了您的输入data.frame d

d2 <- expand.grid(apply(unique(d[,c("SITE","DATE")]), 1, paste, collapse=" "),
                  unique(d$SAMPLE), unique(d$TAXA))
d2 <- cbind(matrix(unlist(strsplit(as.character(d2$Var1), " ")), ncol=2, byrow=TRUE),
            d2[,2:3])
names(d2)<-names(d)[1:4]

d2 <- merge(d2,d, all.x=TRUE)

d2[which(is.na(d2), arr.ind=TRUE)] <- 0

输出:

   SITE      DATE SAMPLE TAXA X1 X2 X3
1   NSV 23-Oct-13   Pool    1 10 10 10
2   NSV 23-Oct-13   Pool    2 10 10 10
3   NSV 23-Oct-13   Pool  100  0  0  0
4   NSV 23-Oct-13   Pool  150  0  0  0
5   NSV 23-Oct-13 Riffle    1 10 10 10
6   NSV 23-Oct-13 Riffle    2 10 10 10
7   NSV 23-Oct-13 Riffle  100  0  0  0
8   NSV 23-Oct-13 Riffle  150  0  0  0
9   NSV  8-Jul-13   Pool    1 10 10 10
10  NSV  8-Jul-13   Pool    2 10 10 10
11  NSV  8-Jul-13   Pool  100  0  0  0
12  NSV  8-Jul-13   Pool  150  0  0  0
13  NSV  8-Jul-13 Riffle    1 10 10 10
14  NSV  8-Jul-13 Riffle    2 10 10 10
15  NSV  8-Jul-13 Riffle  100  0  0  0
16  NSV  8-Jul-13 Riffle  150  0  0  0
17  SFP 27-Oct-13   Pool    1 10 10 10
18  SFP 27-Oct-13   Pool    2 10 10 10
19  SFP 27-Oct-13   Pool  100 10 10 10
20  SFP 27-Oct-13   Pool  150 10 10 10
21  SFP 27-Oct-13 Riffle    1 10 10 10
22  SFP 27-Oct-13 Riffle    2 10 10 10
23  SFP 27-Oct-13 Riffle  100 10 10 10
24  SFP 27-Oct-13 Riffle  150 10 10 10
25  SFP  4-Jul-13   Pool    1 10 10 10
26  SFP  4-Jul-13   Pool    2 10 10 10
27  SFP  4-Jul-13   Pool  100  0  0  0
28  SFP  4-Jul-13   Pool  150  0  0  0
29  SFP  4-Jul-13 Riffle    1 10 10 10
30  SFP  4-Jul-13 Riffle    2 10 10 10
31  SFP  4-Jul-13 Riffle  100  0  0  0
32  SFP  4-Jul-13 Riffle  150  0  0  0