I have a list of vectors and I wish to check them and add the ones that are not empty into a data frame. My main issue when doing this is keeping the vector names so I can then add them. My data is as follows;
att1 = 5
att2 = 4
att3 = character()
att4 = 8
scoresDf = data.frame(att1,att2,att3,att4)
This cannot be made into a dataframe as att3 in this case is empty. Therefore I need to find out which of my columns is empty and only add the ones to the df what are length()>0. When I test which vectors are length>0 my issue is i cant keep the vector names to insert into my data frame.
What I am trying to do is something like;
goodData = #my vectors that are not empty
scoresDf = data.frame(goodData)
I have a list of vectors and I wish to check them and add the ones that are not empty into a data frame. My main issue when doing this is keeping the vector names so I can then add them. My data is as follows;
att1 = 5
att2 = 4
att3 = character()
att4 = 8
scoresDf = data.frame(att1,att2,att3,att4)
This cannot be made into a dataframe as att3 in this case is empty. Therefore I need to find out which of my columns is empty and only add the ones to the df what are length()>0. When I test which vectors are length>0 my issue is i cant keep the vector names to insert into my data frame.
What I am trying to do is something like;
goodData = #my vectors that are not empty
scoresDf = data.frame(goodData)
Share
Improve this question
edited 21 hours ago
Joe
asked 21 hours ago
JoeJoe
1,3875 silver badges21 bronze badges
4
|
3 Answers
Reset to default 3You might want to make your toy data more real.
1) Exactly one element
att1 = 5
att2 = 4
att3 = character()
att4 = 8
L = mget(ls(pattern='^att\\d+$'))
X = list2DF(L[lengths(L)==1])
> str(X)
'data.frame': 1 obs. of 3 variables:
$ att1: num 5
$ att2: num 4
$ att4: num 8
> X
att1 att2 att4
1 5 4 8
2) At least one element
att1 = 5
att2 = 4
att3 = character()
att4 = 8
att5 = 1:2
L = mget(ls(pattern='^att\\d+$')) |>
Filter(f=length)
lapply(L, `length<-`, max(lengths(L))) |>
list2DF()
att1 att2 att4 att5
1 5 4 8 1
2 NA NA NA 2
Note
If length cannot be different from 0
or 1
, why not returning a (named) list
or numeric
vector instead of a data.frame
(list of vectors)?
att1 = 5
att2 = 4
att3 = character()
att4 = 8
#att5 = 1:2
> mget(ls(pattern='^att\\d+$')) |> Filter(f=length)
$att1
[1] 5
$att2
[1] 4
$att4
[1] 8
> # or
> mget(ls(pattern='^att\\d+$')) |> Filter(f=length) |> unlist()
att1 att2 att4
5 4 8
att1 = 5
att2 = 4
att3 = character()
att4 = 8
scoresDf = list(att1=att1,
att2=att2,
att3=att3,
att4=att4)
hasData <- sapply(scoresDf, function(x) {length(x) != 0} )
data.frame(scoresDf[hasData])
returns:
> data.frame(scoresDf[hasData])
att1 att2 att4
5 4 8
Another implementation is using subset
+ lengths
to filter out the empty entries, e.g.,
mget(ls(pattern = "^att\\d")) %>%
subset(!!lengths(.)) %>%
list2DF()
data.frame
what is of same length (exception list columns). You can dolengths(mget(ls(pattern='^att\\d+$')))
to check lengths. empty is of length zero here. I.e.L = mget(ls(pattern='^att\\d+$')); X = list2DF(L[lengths(L)==1]); str(X)
– Friede Commented 21 hours ago