Reputation: 724
I have a dataframe whose columns consists of randomly distributed values and NAs, as seen below:
a<-c("S","E","NA","S","NA")
b<-c("A","NA","M","G","K")
c<-c("I","NA","NA","NA","L")
meh<-dataframe(a,b,c)
# [,1] [,2] [,3] [,4] [,5]
#a "S" "E" "NA" "S" "NA"
#b "A" "NA" "M" "G" "K"
#c "I" "NA" "NA" "NA" "L"
I want to remove all NAs and shift the non-NAs to the left - it should look like this
# [,1] [,2] [,3] [,4]
#a "S" "E" "S"
#b "A" "M" "G" "K"
#c "I" "L"
Any ideas?
Upvotes: 4
Views: 3080
Reputation: 4024
Once the vectors are all different sizes, it doesn't make sense to colbind them back into wide form. Instead,
library(dplyr)
library(tidyr)
meh %>%
gather(variable, value) %>%
filter(!is.na(value))
Upvotes: 0
Reputation: 887531
We can also use stri_list2matrix
library(stringi)
stri_list2matrix(lapply(meh, function(x) x[x!='NA']), fill='', byrow=TRUE)
# [,1] [,2] [,3] [,4]
#[1,] "S" "E" "S" ""
#[2,] "A" "M" "G" "K"
#[3,] "I" "L" "" ""
Upvotes: 1
Reputation: 76
It might help if you specify what you want to do with the data after you finish this process, but here's a way to get rid of NA's in the each column and store them to a variable. That is if you actually have NA's. I changed your example dataset to reflect the comments above to include NA not "NA".
a<-c("S","E",NA,"S",NA)
b<-c("A",NA,"M","G","K")
c<-c("I",NA,NA,NA,"L")
meh<-data.frame(a,b,c)
newcol<-na.omit(meh$a) #Removes all NA's from your column
newcol<-newcol[1:length(newcol)] #Gives you an output without any NA's
The same can be done with each row like jeremycg suggests, using lapply.
lapply(1:nrow(meh), function(x) meh[x,][is.na(meh[x,])==F])
Upvotes: 1