Home > Software engineering >  Merge list items with similar content in r?
Merge list items with similar content in r?

Time:11-10

I have list v:

v <- list(c("12", "1"), c("12", "2"), c("12", "3"), c("13", "1"), c("22", "3"), c("30", "4"))

and I need to merge the lines of this list which share the same first number by joining the second numbers separated by a comma, such that the resulting list w is like this:

w <- list(c("12", "1,2,3"), c("13", "1"), c("22", "3"), c("30", "4"))

How do I go about this? Thank you in advance!

How do I go about this? Thank you in advance!

How do I go about this? Thank you in advance!

> vv <- do.call(rbind.data.frame, v)
> names(vv) <- c("v1", "v2")
> vv
  v1 v2
1 12  1
2 12  2
3 12  3
4 13  1
5 22  3
6 30  4
> vvv <-vv %>%
    group_by(v1) %>%
    summarise(v3 = paste0(v2, collapse = ",")) 
> vvv
# A tibble: 4 x 2
  v1    v3   
  <fct> <chr>
1 12    1,2,3
2 13    1    
3 22    3    
4 30    4    
> w <- as.list(as.data.frame(t(vvv)))
> w
$V1
   v1    v3 
   12 1,2,3 
Levels: 1,2,3 12

$V2
v1 v3 
13  1 
Levels: 1 13

$V3
v1 v3 
22  3 
Levels: 22 3

$V4
v1 v3 
30  4 
Levels: 30 4

> w <- lapply(as.list(1:dim(vvv)[1]), function(x) as.character(vvv[x[1],]))
> w
[[1]]
[1] "1"     "1,2,3"

[[2]]
[1] "2" "1"

[[3]]
[1] "3" "3"

[[4]]
[1] "4" "4"

> w <- base::lapply(as.list(1:dim(vvv)[1]), function(x) as.character(vvv[x[1],]))
> w
[[1]]
[1] "1"     "1,2,3"

[[2]]
[1] "2" "1"

[[3]]
[1] "3" "3"

[[4]]
[1] "4" "4"

CodePudding user response:

You may try

library(dplyr)

vv <- do.call(rbind.data.frame, v)
names(vv) <- c("v1", "v2")
vvv <-vv %>%
  group_by(v1) %>%
  summarise(v3 = paste0(v2, collapse = ",")) 
w <- as.list(as.data.frame(t(vvv)))
w



$V1
[1] "12"    "1,2,3"

$V2
[1] "13" "1" 

$V3
[1] "22" "3" 

$V4
[1] "30" "4" 



w <- lapply(as.list(1:dim(vvv)[1]), function(x) as.character(vvv[x[1],]))
w

[[1]]
[1] "12"    "1,2,3"

[[2]]
[1] "13" "1" 

[[3]]
[1] "22" "3" 

[[4]]
[1] "30" "4" 

Try this

v <- list(c("12", "1"), c("12", "2"), c("12", "3"), c("13", "1"), c("22", "3"), c("30", "4"))
vv <- do.call(rbind.data.frame, v)
names(vv) <- c("v1", "v2")
vv

  v1 v2
1 12  1
2 12  2
3 12  3
4 13  1
5 22  3
6 30  4

vvv <-vv %>%
  dplyr::group_by(v1) %>%
  dplyr::summarise(v3 = paste0(v2, collapse = ",")) 
vvv

  v1    v3   
  <chr> <chr>
1 12    1,2,3
2 13    1    
3 22    3    
4 30    4 

w <- lapply(as.list(1:dim(vvv)[1]), function(x) as.character(vvv[x[1],]))
w

[[1]]
[1] "12"    "1,2,3"

[[2]]
[1] "13" "1" 

[[3]]
[1] "22" "3" 

[[4]]
[1] "30" "4" 

Using data.table

library(data.table)
lapply(seq_len(nrow(vvv)),
       function(i) as.character(setDF(lapply(vvv, "[", i))))

This may solve

v <- list(c("12", "1"), c("12", "2"), c("12", "3"), c("13", "1"), c("22", "3"), c("30", "4"))
vv <- do.call(rbind.data.frame, v)
names(vv) <- c("v1", "v2")
vvv <-vv %>%
  dplyr::group_by(v1) %>%
  dplyr::summarise(v3 = paste0(v2, collapse = ",")) %>% 
  mutate(v1 = as.character(v1))
w <- lapply(as.list(1:dim(vvv)[1]), function(x) as.character(vvv[x[1],]))
w

CodePudding user response:

A base R option using apply family of functions

#get 1st value from each list
group_values <- sapply(v, `[[`, 1)

#For each unique group value combine all the other values in one 
#comma separated string
Map(c, unique(group_values), 
    tapply(v, group_values, function(x) 
    toString(unlist(sapply(x, tail, -1)))))

#$`12`
#[1] "12"      "1, 2, 3"

#$`13`
#[1] "13" "1" 

#$`22`
#[1] "22" "3" 

#$`30`
#[1] "30" "4" 
  • Related