1

I have a data frame of different states over time for >50,000 different individuals. The states are a mix of whole numbers, decimals, NULLs, and chars. I would like to apply the ceiling() function to the data frame but only change the numeric values while keeping everything else the same.

structure(list(`11/1/2014` = c("0", "NULL", "NULL", "NULL", "NULL", 
    "NULL"), `12/1/2014` = c("0", "0", "0", "0", "0", "0"), `1/1/2015` = c("0", 
    "0", "0", "0", "S", "0"), `2/1/2015` = c("0", "0", "1.72", "0", 
    "S", "0")), row.names = c(NA, 6L), class = "data.frame")
Scarabee
  • 5,437
  • 5
  • 29
  • 55
cpage
  • 119
  • 6
  • 27
  • All three columns are `character`, so this is a no-op. Can you provide actual data? I suggest you follow suggestions in [reproducible examples](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example), perhaps using `dput(x)` (but only with a *sample* of the data if large). – r2evans Jul 03 '18 at 20:24
  • 1
    Said differently: in a standard `data.frame`, you cannot have numbers, letters, and even the special `NULL` in a single column. Once you have a single letter in a column of numbers (integer or floating-point), it converts all numbers into strings. It is very hard to embed a true `NULL` (not a string of `"NULL"`) into a frame's column, though it is certainly possible (with nesting). – r2evans Jul 03 '18 at 20:27

1 Answers1

1

Non-numeric values become NAs when you try to coerce them to numeric. So you could use a function like this one:

ceil <- function(x) {
  x_num <- suppressWarnings(as.numeric(x))
  ifelse(!is.na(x_num),
         as.character(ceiling(x_num)),
         as.character(x))
}

transmute_all(yourdataframe, ceil)
#   11/1/2014 12/1/2014 1/1/2015 2/1/2015
# 1         0         0        0        0
# 2      NULL         0        0        0
# 3      NULL         0        0        2
# 4      NULL         0        0        0
# 5      NULL         0        S        S
# 6      NULL         0        0        0
Scarabee
  • 5,437
  • 5
  • 29
  • 55