Replace integer(0) by NA
Asked Answered
L

3

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)).

Latreshia answered 19/1, 2014 at 14:32 Comment(13)
would data.frame$column[data.frame$column == integer(0) ] <- NA work ?Monody
@pepsimax why don't you put that as an answer (maybe provide a working example)?Gingras
A data frame cannot contain integer(0). Please provide a reproducible example.Curren
or you can check for length()==0 see: https://mcmap.net/q/143459/-how-to-catch-integer-0Dub
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)).Sore
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] $<NA> integer(0) > is.na(temp[1,tn1]) <NA> FALSE > class(temp) [1] "data.frame" > class(temp[tn1]) [1] "data.frame" > class(temp[1,tn1]) [1] "list"Latreshia
I appear to have a list inside a data.frame inside a data.frame - which is weird.....Latreshia
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 ...)Faunie
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: #21216205Latreshia
tn1 is a column name. str(temp) output is vast - I don't think you want it on here!Latreshia
ok I think I've given a reproducible example nowLatreshia
Don't reinvent the wheel. Try merge(df1, df2, all.x = TRUE)Cauley
flodel the problem is solved. Can't use merge in any caseLatreshia
C
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
Curren answered 19/1, 2014 at 15:7 Comment(1)
Thanks Sven! That sorted out my problem by incorporating parts of it into my function! Many thanks everyone - apologies for the poor original question!Latreshia
M
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)
}
Mina answered 19/1, 2014 at 14:48 Comment(3)
Correct. Quite un-idiomatic code, though: function (x, ...) if (length(ret) == 0) NA else retZwick
Thanks Ben and Konrad! Appreciate your answers!Latreshia
Thanks Calimo I realise now you answered and Ben editedLatreshia
L
0

Use lengths() like:

 column = list(45L, 64L, integer(0), 78L)
 column[as.logical(lengths(column))] # list
#> [[1]]
#> [1] 45
#> 
#> [[2]]
#> [1] 64
#> 
#> [[3]]
#> [1] 78
 # or 
 unlist(column[as.logical(lengths(column))]) # vector ( c() )
#> [1] 45 64 78
Lucais answered 19/7, 2024 at 11:24 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.