插入空行以完成列的大小写

时间:2015-11-06 22:35:45

标签: r dataframe data.table

我们说我有一个data.table

col1   col2    col3
 a     123      1
 a     433      2
 a     322      3       
 b     43       1  
 b     4333     2
 c     43       1

在上表中,col1的每个类别应该有3行。但只有类别a有3行。因此,我想插入带有NAs的空行,以查找其他类别col1的缺失案例。输出看起来像

col1   col2    col3
 a     123      1
 a     433      2
 a     322      3       
 b     43       1  
 b     4333     2
 b     NA       3
 c     43       1
 c     NA       2
 c     NA       3

如何通过一次调用函数来实现它?

3 个答案:

答案 0 :(得分:3)

data.table 我认为这个成语是col1col3

的笛卡尔/叉积的合并

(同样在@Jealie和@ PLapointe的回答中):

DT[CJ(col1 = col1, col3 = col3, unique=TRUE), on = c("col1", "col3")]

   col1 col2 col3
1:    a  123    1
2:    a  433    2
3:    a  322    3
4:    b   43    1
5:    b 4333    2
6:    b   NA    3
7:    c   43    1
8:    c   NA    2
9:    c   NA    3

CJ构建了交叉产品,A[B,on=cols]与结果中的所有B行合并。

tidyr 在data.table之外,另一种语法更好的替代方案是tidyr:

library(tidyr)
complete(DT, col1, col3)

不幸的是,这不会返回data.table。您可以在结果上使用setDT来解决此问题。

答案 1 :(得分:1)

我会使用merge的应用程序(适用于data.tabledata.frame)。

让我们首先创建一个我们想要的模式:

> pattern = data.frame(col1=rep(letters[1:3], each=3), col3=rep(1:3,3))
> pattern
  col1 col3
1    a    1
2    a    2
3    a    3
4    b    1
5    b    2
6    b    3
7    c    1
8    c    2
9    c    3

然后将此模式与实际数据合并:

> merge(pattern, real_data, all.x=T, by=c('col1','col3'))
  col1 col3 col2
1    a    1  123
2    a    2  433
3    a    3  322
4    b    1   43
5    b    2 4333
6    b    3   NA
7    c    1   43
8    c    2   NA
9    c    3   NA

注意:real_data来自:

# data.table:
real_data = structure(list(col1 = structure(c(1L, 1L, 1L, 2L, 2L, 3L), .Label = c("a", "b", "c"), class = "factor"), col2 = c(123L, 433L, 322L, 43L, 4333L, 43L), col3 = c(1L, 2L, 3L, 1L, 2L, 1L)), .Names = c("col1", "col2", "col3"), class = c("data.table","data.frame"), row.names = c(NA, -6L))
# or data.frame:
real_data = structure(list(col1 = structure(c(1L, 1L, 1L, 2L, 2L, 3L), .Label = c("a", "b", "c"), class = "factor"), col2 = c(123L, 433L, 322L, 43L, 4333L, 43L), col3 = c(1L, 2L, 3L, 1L, 2L, 1L)), .Names = c("col1", "col2", "col3"), class = "data.frame", row.names = c(NA, -6L))

答案 2 :(得分:1)

或者您可以在full_join中使用dplyr

table1 <-read.table(text="col1   col2    col3
 a     123      1
 a     433      2
 a     322      3
 b     43       1
 b     4333     2
 c     43       1", header=T,stringsAsFactors =F)

library(dplyr)
all1 <-expand.grid(letters[1:3],1:3, stringsAsFactors = F)
colnames(all1) <-c("col1","col3")
full_join(table1,all1,c("col1","col3"))

  col1 col2 col3
1    a  123    1
2    a  433    2
3    a  322    3
4    b   43    1
5    b 4333    2
6    c   43    1
7    c   NA    2
8    b   NA    3
9    c   NA    3