Provisional.Modulation
Provisional.Modulation

Reputation: 724

Dataframe manipulation in R - Shift cells to the left and remove NAs

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

Answers (3)

bramtayl
bramtayl

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

akrun
akrun

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

jscole
jscole

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

Related Questions