Hope I am not duplicating another's question and perhaps a similar vein to my other question.
I am trying to
IDMy data df
df <- read.table(text =
" ID Product
1 1 A
2 1 A
3 1 A
4 2 NA
5 2 NA
6 3 P
7 3 P
8 4 A
9 4 P
10 5 A
11 6 P
12 7 NA ")
My desired output:
ID Product Group
1 1 A A
2 1 A A
3 1 A A
4 2 NA NA
5 2 NA NA
6 3 P P
7 3 P P
8 4 A A_P
9 4 P A_P
10 5 A A
11 6 P P
12 7 NA NA
I've tried a few things, but the new column does not emerge:
df$Group <- df %>%
group_by(ID) %>%
ifelse(all(df$Product==A), "A",
ifelse(all(df$Product==P), "P",
ifelse(all(df$Product==NA), "NA", "A_P") %>%
ungroup()
I've also tried:
df$group <- df%>%
group_by(ID) %>%
if(all(df$Product=="A") {
df$group="A"
} else if(all(df$Product=="P") {
df$group="P"
} else if(all(df$Product==NA) {
df$group=NA
} else {df$group="A_P"}
But it keeps saying that my } is not supposed to be there which doesn't make sense to me?
My other question: Can you use all in ifelse statements for non-numerical vectors?
Thanks.
Using ave, avoiding if-else.
transform(df, Group=ave(Product, ID, FUN=\(x) {
u <- paste(sort(unique(x)), collapse='_');replace(u, u == '', NA)}))
# ID Product Group
# 1 1 A A
# 2 1 A A
# 3 1 A A
# 4 2 <NA> <NA>
# 5 2 <NA> <NA>
# 6 3 P P
# 7 3 P P
# 8 4 A A_P
# 9 4 P A_P
# 10 5 A A
# 11 6 P P
# 12 7 <NA> <NA>
maybe consider toString to make it comma-separated
transform(df, Group=ave(Product, ID, FUN=\(x) {
u <- toString(sort(unique(x)));replace(u, u == '', NA)}))
# ID Product Group
# 1 1 A A
# 2 1 A A
# 3 1 A A
# 4 2 <NA> <NA>
# 5 2 <NA> <NA>
# 6 3 P P
# 7 3 P P
# 8 4 A A, P
# 9 4 P A, P
# 10 5 A A
# 11 6 P P
# 12 7 <NA> <NA>
Data:
df <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L,
6L, 7L), Product = c("A", "A", "A", NA, NA, "P", "P", "A", "P",
"A", "P", NA)), class = "data.frame", row.names = c("1", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
Here's my stab using base R and a few readable lines of code. :)
xy <- read.table(text =
" ID Product
1 1 A
2 1 A
3 1 A
4 2 NA
5 2 NA
6 3 P
7 3 P
8 4 A
9 4 P
10 5 A
11 6 P
12 7 NA ")
xygroup <- split(x = xy, f = xy$ID)
xy.withgroup <- lapply(X = xygroup, FUN = function(x) {
unique.products <- unique(x$Product)
if (all(is.na(unique.products))) {
group <- NA
} else {
group <- paste(unique.products, collapse = "_")
}
x$Group <- group
x
})
do.call(rbind, xy.withgroup)
ID Product Group
1.1 1 A A
1.2 1 A A
1.3 1 A A
2.4 2 <NA> <NA>
2.5 2 <NA> <NA>
3.6 3 P P
3.7 3 P P
4.8 4 A A_P
4.9 4 P A_P
5 5 A A
6 6 P P
7 7 <NA> <NA>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With