kin182
kin182

Reputation: 403

How to paste individually in a list if the vectors are different in lengths

I have a question on how to use the paste function in a list if its vectors are of different lengths. I have a dataframe with columns of different lengths, such as:

df = data.frame(Set1=c("abc",'def',"ghi","jkl",""), Set2=c("abc",'def',"","",""), Set3=c("mno","pqr","stu","vwx","xyz"))

I tried to make a list a.list based on each column and collapse each factor with a ,. Something like

a.list

$Set1
[1] abc,def,ghi,jkl

$Set2
[1] abc,def

$Set3
[1] mno,pqr,stu,vwx,xyz

I tried

> a.list = apply(df, 2, as.list)
> a.list = lapply(a.list, function(x) paste(x, collapse=",")

However, it collapsed the factors with , to the maximum length of the list. For example,

a.list

$Set1
[1] "abc,def,ghi,jkl,"

$Set2
[1] "abc,def,,,"

Sorry it may be a simple question. I am still learning R. Thanks!

Upvotes: 2

Views: 195

Answers (2)

akrun
akrun

Reputation: 887213

We can remove the '' with setdiff after looping over the columns with lapply, then paste the rest of the elements (toString). Note that toString => paste(..., collapse=", ")

lapply(df, function(x) toString(setdiff(x, '')))

This assumes that there are unique elements in the column. If there are duplicates, use vsetdiff

library(vecsets)
lapply(df, function(x) toString(vsetdiff(x, '')))

Or using nzchar

lapply(df, function(x) toString(x[nzchar(x)]))
#$Set1
#[1] "abc, def, ghi, jkl"

#$Set2
#[1] "abc, def"

#$Set3
#[1] "mno, pqr, stu, vwx, xyz"

Also, it may be better to return a vector instead of list as each element of the list is of length 1

sapply(df, function(x) toString(x[nzchar(x)]))

Or using tidyverse

library(dplyr)
library(stringr)
df %>% 
   summarise(across(everything(), ~ str_c(.[nzchar(.)], collapse=",")))

NOTE: We don't need to create a logical vector with != as nzchar already does that

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389012

You can remove the empty values from each element in the list and paste the values.

lapply(df, function(x) paste(x[x!=''], collapse = ","))

#$Set1
#[1] "abc,def,ghi,jkl"

#$Set2
#[1] "abc,def"

#$Set3
#[1] "mno,pqr,stu,vwx,xyz"

Upvotes: 1

Related Questions