8

I have a function that I apply to a column and puts results in another column and it sometimes gives me integer(0) as output. So my output column will be something like:

45
64
integer(0)
78

How can I detect these integer(0)'s and replace them by NA? Is there something like is.na() that will detect them ?


Edit: Ok I think I have a reproducible example:

df1 <-data.frame(c("267119002","257051033",NA,"267098003","267099020","267047006"))
names(df1)[1]<-"ID"

df2 <-data.frame(c("257051033","267098003","267119002","267047006","267099020"))
names(df2)[1]<-"ID"
df2$vals <-c(11,22,33,44,55)

fetcher <-function(x){
  y <- df2$vals[which(match(df2$ID,x)==TRUE)]
return(y) 
}

sapply(df1$ID,function(x) fetcher(x))

The output from this sapply is the source of the problem.

> str(sapply(df1$ID,function(x) fetcher(x)))
List of 6
$ : num 33
$ : num 11
$ : num(0) 
$ : num 22
$ : num 55
$ : num 44

I don't want this to be a list - I want a vector, and instead of num(0) I want NA (note in this toy data it gives num(0) - in my real data it gives (integer(0)).

user2498193
  • 1,072
  • 2
  • 13
  • 32
  • 2
    would data.frame$column[data.frame$column == integer(0) ] <- NA work ? – cianius Jan 19 '14 at 14:36
  • 1
    @pepsimax why don't you put that as an answer (maybe provide a working example)? – Roman Luštrik Jan 19 '14 at 14:36
  • 2
    A data frame cannot contain `integer(0)`. Please provide a reproducible example. – Sven Hohenstein Jan 19 '14 at 14:37
  • 1
    or you can check for `length()==0` see: http://stackoverflow.com/questions/6451152/how-to-catch-integer0 – holzben Jan 19 '14 at 14:44
  • 1
    I am also interested to see how `integer(0)` did get into your output. But to get you going: To test if an object is `integer(0)` you could do `identical(object, integer(0))`. – Mark Heckmann Jan 19 '14 at 14:44
  • pepsimax tried that doesn't work. Sven I tried to make a reproducible example and I could not. Its not possible to post the whole project here. I'll take another look at it. Here is the output from looking at my live data: `> temp[1,tn1] $ integer(0) > is.na(temp[1,tn1]) FALSE > class(temp) [1] "data.frame" > class(temp[tn1]) [1] "data.frame" > class(temp[1,tn1]) [1] "list"` – user2498193 Jan 19 '14 at 14:56
  • I appear to have a list inside a data.frame inside a data.frame - which is weird..... – user2498193 Jan 19 '14 at 14:59
  • I'm voting to close, because without a reproducible example it's nearly impossible to help you ... it would help a little if you could edit your question to show the results of `str(temp)` (and tell us what `tn1` is ...) – Ben Bolker Jan 19 '14 at 15:01
  • Yeah sorry Ben I realise it is a bad question - seemingly I don't understand how I created this weirdness in the first place. Perhaps I need to take a step back. This situation came about after applying this logic to my live dataset: http://stackoverflow.com/questions/21215705/r-passing-variable-name-into-sapply/21215819?noredirect=1#21215819 – user2498193 Jan 19 '14 at 15:04
  • tn1 is a column name. str(temp) output is vast - I don't think you want it on here! – user2498193 Jan 19 '14 at 15:06
  • ok I think I've given a reproducible example now – user2498193 Jan 19 '14 at 15:13
  • Don't reinvent the wheel. Try `merge(df1, df2, all.x = TRUE)` – flodel Jan 20 '14 at 00:14
  • flodel the problem is solved. Can't use merge in any case – user2498193 Jan 20 '14 at 01:21

2 Answers2

7

Here's a way to (a) replace integer(0) with NA and (b) transform the list into a vector.

# a regular data frame
> dat <- data.frame(x = 1:4)
# add a list including integer(0) as a column
> dat$col <- list(45,
+                 64,
+                 integer(0),
+                 78)
> str(dat)
'data.frame':   4 obs. of  2 variables:
 $ x  : int  1 2 3 4
 $ col:List of 4
  ..$ : num 45
  ..$ : num 64
  ..$ : int 
  ..$ : num 78
# find zero-length values
> idx <- !(sapply(dat$col, length))
# replace these values with NA
> dat$col[idx] <- NA
# transform list to vector
> dat$col <- unlist(dat$col)
# now the data frame contains vector columns only
> str(dat)
'data.frame':   4 obs. of  2 variables:
 $ x  : int  1 2 3 4
 $ col: num  45 64 NA 78
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
  • Thanks Sven! That sorted out my problem by incorporating parts of it into my function! Many thanks everyone - apologies for the poor original question! – user2498193 Jan 19 '14 at 15:28
4

Best to do that in your function, I'll call it myFunctionForApply but that's your current function. Before you return, check the length and if it is 0 return NA:

myFunctionForApply <- function(x, ...) {
    # Do your processing
    # Let's say it ends up in variable 'ret':
    if (length(ret) == 0)
        return(NA)
    return(ret)
}
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
Calimo
  • 7,510
  • 4
  • 39
  • 61