这是一个潜在的,如果有点不雅,解决方案
out <- with(dat, split(dat, interaction(column2, column3)))
out <- lapply(out, function(x) if(NROW(x) > 1) {NULL} else {data.frame(x)})
out <- out[!sapply(out, is.null)]
do.call(rbind, out)
这使:
> do.call(rbind, out)
row.no column2 column3 column4
bb.yy 4 bb yy down
bb.zz 5 bb zz up
一些解释,逐行:
- 第 1 行:将数据拆分为一个列表,其中的每个组件都是一个数据框,其中的行对应于由 和 的唯一组合形成的
column2
组column3
。
- 第 2 行:迭代第 1 行的结果;如果数据框中有超过 1 行,则返回 NULL,如果没有,则返回 1 行数据框。
- 第 3 行:迭代第 2 行的输出;仅返回非 NULL 组件
- 第 4 行:需要逐行绑定第 3 行的输出,我们通过
do.call()
这可以简化为两行,将第 1-3 行合并为一行:
out <- lapply(with(dat, split(dat, interaction(column2, column3))),
function(x) if(NROW(x) > 1) {NULL} else {data.frame(x)})
do.call(rbind, out[!sapply(out, is.null)])
以上全部完成:
dat <- structure(list(row.no = 1:5, column2 = structure(c(1L, 1L, 1L,
1L, 1L), .Label = "bb", class = "factor"), column3 = structure(c(1L,
1L, 1L, 2L, 3L), .Label = c("ee", "yy", "zz"), class = "factor"),
column4 = structure(c(2L, 1L, 2L, 1L, 2L), .Label = c("down",
"up"), class = "factor")), .Names = c("row.no", "column2",
"column3", "column4"), class = "data.frame", row.names = c(NA,
-5L))