EDITAR
Tengo un marco de datos como el siguiente: tenga en cuenta que COL1
está teniendo entradas duplicadas, COL2 y COL3 pueden seren cualquier orden, es decir, pueden ocurrir en cualquier lugar entre otras columnas en el marco de datos ... y no hay limitación en el número exacto de columnas en el marco de datos ... puede haber columnas adicionales también agregadas más tarde .....
COL1 COL2 COL3 COL5 COL6 COL7 ... ... (goes on)
10 hai 2 15 10 6 ... ...
10 hai 3 25 20 12 ... ...
10 pal 1 35 30 18 ... ...
11 rfm 9 22 32 9 ... ...
9 rtf 8 34 54 10 ... ...
También tengo un vector como el siguiente:
number <- c("first", "last")
Quiero que la salida sea así como se muestra a continuación: es decir
COL1
debe tener solo la entrada única (10,11,9)COL2
debe contener las entradas fusionadas debajo sin duplicados (hai pal), las filas únicas con valores COL1 distintos no deberían "tser considerado para fusionarse. Solo se deben combinar filas duplicadas de valores COL1 ... y COL2 puede aparecer en cualquier parte del marco de datos (no siempre será la segunda columna)COL3
debe contener la suma de las entradas (2 + 3 + 1 = 6). La suma debe calcularse solo para filas duplicadas. Las filas duplicadas se identifican en función de los valores de COL1 ... y COL3 también puede aparecer en cualquier parte del marco de datos (no siempre será la tercera columna).
Y para COL5
, COL6
, COL7
(Es posible que tenga muchas columnas agregadas más tarde ...no es necesario que solo tenga 3 columnas para esta condición) necesito un fragmento de código generalizado de modo que si la entrada se da como "primera" del vector llamado "número", los valores de la primera observación de las filas duplicadas de todas las columnas restantes deben tomarse, es decir, los valores de la primera fila. Y si la entrada se da como "última" del vector llamado "número", los valores de la última observación de las filas duplicadas de todas las columnas restantes deben tomarse, es decir, los valores de la última fila.
Nota: La salida debe almacenarse en otro marco de datos
SALIDA (si la entrada se da como "primera"):
COL1 COL2 COL3 COL5 COL6 COL7
10 hai pal 6 15 10 6
11 rfm 9 22 32 9
9 rtf 8 34 54 10
En el resultado anterior: COL5, COL6, COL7 contienen los valores de la primera fila de entradas duplicadas
SALIDA (si la entrada se da como "última"):
COL1 COL2 COL3 COL5 COL6 COL7
10 hai pal 6 15 10 6
11 rfm 9 22 32 9
9 rtf 8 34 54 10
En el resultado anterior: COL5, COL6, COL7 contienen los valores de la última fila de entradas duplicadas
Respuestas
2 para la respuesta № 1Nosotros podemos usar data.table
library(data.table)
setDT(df1)[, .(COL2 = paste(unique(COL2), collapse= " "),
COL3 = sum(COL3),
COL5 = COL5[1L],
COL6 = COL6[1L],
COL7 = COL7[1L]), by = COL1]
# COL1 COL2 COL3 COL5 COL6 COL7
#1: 10 hai pal 6 15 10 6
Si estamos usando la versión de desarrollo de data.table
es decir, v.1.9.7, entonces esto se puede simplificar como
setDT(df1)[, c(COL2 = paste(unique(COL2), collapse=" "),
COL3 = sum(COL3) ,.SD[1L]), by = COL1, .SDcols=COL5:COL7]
# COL1 COL2 COL3 COL5 COL6 COL7
#1: 10 hai pal 6 15 10 6
Si necesitamos las últimas filas, use .SD[.N]
en lugar de .SD[1L]
es decir
setDT(df1)[, c(COL2 = paste(unique(COL2), collapse=" "),
COL3 = sum(COL3) ,.SD[.N]), by = COL1, .SDcols=COL5:COL7]
# COL1 COL2 COL3 COL5 COL6 COL7
#1: 10 hai pal 6 35 30 18
Las instrucciones para instalar la versión de desarrollo de data.table son aquí
2 para la respuesta № 2
Puedes usar dplyr
.
Esto es básicamente solo una extensión de mi comentario en su pregunta anterior
library(dplyr)
new_df <- df %>% group_by(COL1) %>%
summarise(COL2 = paste0(unique(COL2), collapse = " "),
COL3 = sum(COL3),
COL5 = first(COL5),
COL6 = first(COL6),
COL7 = first(COL7))
new_df
# COL1 COL2 COL3 COL5 COL6 COL7
# <int> <chr> <int> <int> <int> <int>
#1 10 hai pal 6 15 10 6
EDITAR
Puedes hacer una operación similar usando last
en lugar de first
en dplyr
Si solo hay dos opciones (primera, última), puede verificar la condición con un if
declaración
if(number == "first") {
new_df <- df %>% group_by(COL1) %>%
summarise(COL2 = paste0(unique(COL2), collapse = " "),
COL3 = sum(COL3),
COL5 = first(COL5),
COL6 = first(COL6),
COL7 = first(COL7))
} else
{
new_df <- df %>% group_by(COL1) %>%
summarise(COL2 = paste0(unique(COL2), collapse = " "),
COL3 = sum(COL3),
COL5 = last(COL5),
COL6 = last(COL6),
COL7 = last(COL7))
}
1 para la respuesta № 3
Prueba esto con la base R:
get.df <- function(df, input) {
cbind.data.frame(COL1=unique(df$COL1),
COL2=paste(unique(df$COL2), collapse=" "),
COL3=sum(df$COL3),
df[ifelse(input == "first", 1, nrow(df)),names(df)[-1:-3]])
}
get.df(df, "first")
# COL1 COL2 COL3 COL5 COL6 COL7
# 1 10 hai pal 6 15 10 6
get.df(df, "last")
# COL1 COL2 COL3 COL5 COL6 COL7
# 3 10 hai pal 6 35 30 18
Según su nuevo requisito, intente esto:
df <- read.table(text="COL1 COL2 COL3 COL5 COL6 COL7
10 hai 2 15 10 6
10 hai 3 25 20 12
10 pal 1 35 30 18
11 rfm 9 22 32 9
9 rtf 8 34 54 10", header=TRUE)
get.df <- function(df, input) {
dups <- unique(df[duplicated(df$COL1),]$COL1)
df.dup <- df[df$COL1 %in% dups,]
df.nondup <- df[!(df$COL1 %in% dups),]
rbind(cbind.data.frame(COL1=unique(df.dup$COL1),
COL2=paste(unique(df.dup$COL2), collapse=" "),
COL3=sum(df.dup$COL3),
df.dup[ifelse(input == "first", 1, nrow(df.dup)),names(df.dup)[-1:-3]]),
df.nondup)
}
number <- c("first", "last")
get.df(df, "first")
COL1 COL2 COL3 COL5 COL6 COL7
1 10 hai pal 6 15 10 6
4 11 rfm 9 22 32 9
5 9 rtf 8 34 54 10
get.df(df, "last")
COL1 COL2 COL3 COL5 COL6 COL7
3 10 hai pal 6 35 30 18
4 11 rfm 9 22 32 9
5 9 rtf 8 34 54 10