Question

Hi to all the community. I search in the forum, but unsuccessfully for this "easy" question. May be there is already a similar question? I have the following dataframe:

ID<-c(rep(seq(1:5),4))
LAB<-c("A","B","C","A")
datain<-data.frame(cbind(ID,LAB))

I would like to know if exist a function in R to get for each ID the different values(LAB) without duplicates? Like:

ID<-c(rep(seq(1:5),4))
LAB<-c("A B C")
dataout<-data.frame(cbind(ID,LAB))
dataout
ID   LAB
1   1 A B C
2   2 A B C
3   3 A B C
4   4 A B C
5   5 A B C
6   1 A B C
7   2 A B C
8   3 A B C
9   4 A B C
10  5 A B C
11  1 A B C
12  2 A B C
13  3 A B C
14  4 A B C
15  5 A B C
16  1 A B C
17  2 A B C
18  3 A B C
19  4 A B C
20  5 A B C

My apologies for not have specify the output before!!!

As always any help is greatly appreciated!

Was it helpful?

Solution 2

I think you are looking for split:

with(datain, split(LAB, ID))
# $`1`
# [1] A B C A
# Levels: A B C
# 
# $`2`
# [1] B C A A
# Levels: A B C
# 
# $`3`
# [1] C A A B
# Levels: A B C
# 
# $`4`
# [1] A A B C
# Levels: A B C
# 
# $`5`
# [1] A B C A
# Levels: A B C

Since each ID might have a different number of LABs, the output is a list.

Edit: Since it now appears you only wanted unique values, do:

with(unique(datain), split(LAB, ID))

and if you don't like getting factors, do:

with(unique(datain), split(as.character(LAB), ID))

OTHER TIPS

You don't specify what you want your output to look like.

There are several options. Here are two:

aggregate(as.character(LAB) ~ ID, data, c, simplify = FALSE)
#   ID as.character(LAB)
# 1  1        A, B, C, A
# 2  2        B, C, A, A
# 3  3        C, A, A, B
# 4  4        A, A, B, C
# 5  5        A, B, C, A
with(data, tapply(as.character(LAB), ID, FUN = c))
# $`1`
# [1] "A" "B" "C" "A"
# 
# $`2`
# [1] "B" "C" "A" "A"
# 
# $`3`
# [1] "C" "A" "A" "B"
# 
# $`4`
# [1] "A" "A" "B" "C"
# 
# $`5`
# [1] "A" "B" "C" "A"

It's possible you might even be happy with table, if you happen to only be interested in the frequency of each "LAB" by "ID".

table(data)
#    LAB
# ID  A B C
#   1 2 1 1
#   2 2 1 1
#   3 2 1 1
#   4 2 1 1
#   5 2 1 1

Update based on desired output

Now that you've shown us what you want your output to look like, perhaps you can try this:

newout <- merge(datain, 
                aggregate(as.character(LAB) ~ ID, datain, 
                          function(x) paste(sort(unique(x)), collapse = " "), 
                          simplify = FALSE))
head(newout)
#   ID LAB as.character(LAB)
# 1  1   A             A B C
# 2  1   B             A B C
# 3  1   C             A B C
# 4  1   A             A B C
# 5  2   A             A B C
# 6  2   B             A B C
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top