EDYTOWAĆ
Mam ramkę danych jak poniżej: zwróć uwagę na to COL1
ma zduplikowane wpisy, mogą je mieć COL2 i COL3w dowolnej kolejności, tj. mogą wystąpić w dowolnym miejscu między innymi kolumnami w ramce danych ... i nie ma ograniczeń co do dokładnej liczby kolumn w ramce danych ... mogą być też dołączone dodatkowe kolumny później .....
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 ... ...
Mam też wektor jak poniżej:
number <- c("first", "last")
Chcę, aby wynik był taki, jak pokazano poniżej: tj
COL1
powinien mieć sam unikalny wpis (10,11,9)COL2
powinien zawierać scalone wpisy pod nim bez duplikatów (hai pal), unikalne wiersze z różnymi wartościami COL1 nie powinnybrać pod uwagę przy scalaniu. Należy scalać tylko zduplikowane wiersze wartości COL1 ... a COL2 może wystąpić w dowolnym miejscu ramki danych (nie zawsze będzie to druga kolumna)COL3
powinien zawierać sumę wpisów (2 + 3 + 1 = 6). Suma powinna być obliczona tylko dla zduplikowanych wierszy. Zduplikowane wiersze są identyfikowane na podstawie wartości COL1 ... i COL3 może również wystąpić w dowolnym miejscu ramki danych (nie zawsze będzie to trzecia kolumna).
I dla COL5
, COL6
, COL7
(Mogę mieć dołączonych wiele kolumn później ...nie jest konieczne, że mam tylko 3 kolumny dla tego warunku) potrzebuję uogólnionego fragmentu kodu takiego, że jeśli dane wejściowe są podane jako „pierwsze” z wektora o nazwie „liczba”, wartości pierwszej obserwacji ze zduplikowanych wierszy wszystkich pozostałych kolumn należy wziąć, tj. wartości pierwszego wiersza. A jeśli dane wejściowe są podane jako „ostatnie” z wektora o nazwie „liczba”, należy wziąć wartości ostatniej obserwacji ze zduplikowanych wierszy ze wszystkich pozostałych kolumn, tj. Wartości ostatniego wiersza.
Uwaga: Dane wyjściowe powinny być przechowywane w innej ramce danych
WYJŚCIE (jeśli wejście podano jako „pierwsze”):
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
W powyższym wyniku: COL5, COL6, COL7 zawierają wartości pierwszego rzędu zduplikowanych wpisów
WYJŚCIE (jeśli wejście podano jako „ostatnie”):
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
W powyższym wyniku: COL5, COL6, COL7 zawierają wartości ostatniego wiersza zduplikowanych wpisów
Odpowiedzi:
2 dla odpowiedzi № 1Możemy użyć 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
Jeśli używamy rozwojowej wersji data.table
tj. wersja 1.9.7, to można to uprościć jako
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
Jeśli potrzebujemy ostatnich rzędów, użyj .SD[.N]
zamiast .SD[1L]
to znaczy
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
Instrukcje instalacji rozwojowej wersji pliku data.table to tutaj
2 dla odpowiedzi nr 2
Możesz użyć dplyr
.
Jest to po prostu rozszerzenie mojego komentarz na Twoje poprzednie pytanie.
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
EDYTOWAĆ
Możesz wykonać podobną operację za pomocą last
zamiast first
w dplyr
Jeśli są tylko dwie opcje (pierwsza, ostatnia), możesz sprawdzić warunek za pomocą if
komunikat
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 dla odpowiedzi nr 3
Spróbuj tego z podstawą 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
Zgodnie z nowym wymaganiem wypróbuj to:
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