Aquí está uno potencial, aunque algo poco elegante, solución
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)
cual da:
> do.call(rbind, out)
row.no column2 column3 column4
bb.yy 4 bb yy down
bb.zz 5 bb zz up
Algunos explicación, línea por línea:
- Línea 1: divide los datos en una lista, cada componente de las cuales es una trama de datos con filas correspondiente a grupos formados por combinaciones únicas de
column2
y column3
.
- Línea 2: iterar sobre el resultado de la línea 1; si hay más de 1 fila en el marco de datos, devuelva NULL, si no devuelve el marco de datos de 1 fila.
- Línea 3: iterar sobre la salida de la Línea 2; devolver sólo componentes no NULL
- Línea 4: necesitan unirse, de modo de fila, la salida de la línea 3, que disponemos a través de
do.call()
Esto se puede simplificar a dos líneas, la combinación de las líneas 1 -3 en una sola línea:
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)])
Lo anterior fue hecho con:
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))
+1 para usar plyr –