Returning a vector of class POSIXct with vapply
What about do.call
?
L <- list(as.POSIXct("2012-12-12 12:12:12"), as.POSIXct("2012-12-12 12:12:12"))
do.call(c, L) # Execute function c on a list L of arguments.
[1] "2012-12-12 12:12:12 CET" "2012-12-12 12:12:12 CET"
How to make vapply return a date vector?
The problem is that apply
family functions drop Date
class. Here is one way to do it:
do.call("c", lapply(3:7, f1))
You can also add class(result) <- "Date"
after evaluating vapply
.
Full version of class(result) <- "Date"
:
result <- vapply(3:7, f1, numeric(1))
class(result) <- "Date"
result
# "2000-03-01" "2000-04-01" "2000-05-01" "2000-06-01" "2000-07-01"
Passing POSIXct object to function returns numeric vector
We can use lapply
instead of sapply
as sapply
by default has the option simplify = TRUE
. So, if the list
elements are of the same length, it will simplify it to vector
or matrix
depending on the length of the list
elements and POSIXct
is stored as numeric
.
lst <- lapply(dates, function(x) x)
If we need to use sapply
, then an option would simplify = FALSE
lst <- sapply(dates, function(x) x, simplify=FALSE)
After applying the function, if we need as a vector output,
do.call("c", lst)
Regarding the change of timezone, it is documented in the ?DateTimeClasses
Using c on "POSIXlt" objects converts them to the current time zone,
and on "POSIXct" objects drops any "tzone" attributes (even if they
are all marked with the same time zone).
So, the possible option would be (as mentioned in the comments by @kmo)
.POSIXct(lst, tz = "America/Los_Angeles")
#[1] "2012-02-01 12:32:00 PST" "2012-10-24 17:25:56 PDT" "2008-09-26 17:13:31 PDT" "2011-08-23 11:11:17 PDT" "2015-09-19 22:28:33 PDT"
Or as @thelatemail mentioned in the comments
.POSIXct(sapply(dates,I), attr(dates,"tzone") )
Why is POSIXct converted to numeric when converting list to vector
You can reproduce more easily like this:
x <- list(as.POSIXct("2016-11-02"), as.POSIXct("2016-11-03"))
unlist(x)
#[1] 1478041200 1478127600
unlist
combines the values inside the list. The internal representation of POSIXct
variables are numeric values. They only are a POSIXct
variable due to attributes, most importantly the class
attribute. A list can hold all kinds of objects. The documentation says:
Where possible the list elements are coerced to a common mode during
the unlisting, and so the result often ends up as a character vector.
Vectors will be coerced to the highest type of the components in the
hierarchy NULL < raw < logical < integer < double < complex <
character < list < expression: pairlists are treated as lists.
Note that it says "common mode", not common class. Since a class could be anything and could enforce any kind of underlying structure (e.g., it might not even be possible to combine two objects of the same class in a meaningful way), unlist
just strips all attributes (except for a list
where all elements are factors). It would be possible to handle POSIXct
values like factor
values, but that's not the case (and might have performance implications).
You can't avoid this, but fix it easily:
y <- unlist(x)
attributes(y) <- attributes(x[[1]])
y
#[1] "2016-11-02 CET" "2016-11-03 CET"
Obviously this assumes that all list elements have the same timezone attribute.
Understanding why sapply in R returns vector of longer length
To specifically answer the reason for 688 is that you are assigning values by un-ordered indexes from values of calc_size
to the empty vector, likelihoods
. Specifically, calc_sizes
comprises of 87 integer values. Notice the smallest term is 1 and largest term is 688.
calc_sizes
[1] 1 40 2 3 180 4 19 21 10 49 6 18 5 11 81 23 186 189 8
[20] 41 27 20 7 12 68 9 25 16 131 15 51 26 22 17 648 24 30 32
[39] 28 36 53 96 47 14 548 109 38 31 99 106 34 39 607 100 233 42 66
[58] 129 33 170 102 70 13 46 63 79 97 447 460 688 346 130 44 69 620 113
[77] 92 256 153 78 462 325 61 64 54 76 86
However, your intended sapply
also contains 87:
sapply(calc_sizes, nb.likelihood)
[1] -1.098612 -11.788381 -2.602690 -3.413620 -30.541489 -4.001407
[7] -8.187640 -8.575276 -6.146104 -13.154588 -4.881330 -7.987619
[13] -4.475865 -6.410490 -17.680645 -8.948901 -31.297439 -31.674821
[19] -5.565697 -11.943435 -9.663029 -8.383385 -5.240275 -6.661805
[25] -15.886160 -5.865802 -9.310881 -7.572668 -24.292698 -7.356445
[31] -13.450466 -9.488087 -8.763676 -7.782825 -87.586858 -9.131222
[37] -10.175841 -10.509013 -9.835872 -11.158148 -13.744013 -19.702968
[43] -12.856183 -7.133302 -75.557026 -21.425116 -11.475373 -10.343221
[49] -20.102594 -21.029806 -10.836219 -11.632377 -82.659672 -20.235490
[55] -37.171587 -12.097586 -15.605646 -24.034010 -10.673316 -29.277798
[61] -20.500835 -16.165367 -6.902190 -12.705964 -15.182243 -17.407459
[67] -19.836336 -63.355209 -64.929415 -92.388061 -51.074698 -24.163398
[73] -12.403344 -16.025922 -84.222650 -21.950431 -19.167825 -40.021951
[79] -27.117199 -17.270506 -65.171492 -48.507264 -14.898089 -15.323743
[85] -13.889967 -16.995849 -18.359679
So in your assignment you are assigning by indexed positions the values of sapply
, spread out elementwise.
likelihoods[calc_sizes] <- sapply(calc_sizes, nb.likelihood)
likelihoods
[1] -1.098612 -2.602690 -3.413620 -4.001407 -4.475865 -4.881330
[7] -5.240275 -5.565697 -5.865802 -6.146104 -6.410490 -6.661805
[13] -6.902190 -7.133302 -7.356445 -7.572668 -7.782825 -7.987619
[19] -8.187640 -8.383385 -8.575276 -8.763676 -8.948901 -9.131222
[25] -9.310881 -9.488087 -9.663029 -9.835872 NA -10.175841
[31] -10.343221 -10.509013 -10.673316 -10.836219 NA -11.158148
[37] NA -11.475373 -11.632377 -11.788381 -11.943435 -12.097586
[43] NA -12.403344 NA -12.705964 -12.856183 NA
[49] -13.154588 NA -13.450466 NA -13.744013 -13.889967
[55] NA NA NA NA NA NA
[61] -14.898089 NA -15.182243 -15.323743 NA -15.605646
[67] NA -15.886160 -16.025922 -16.165367 NA NA
[73] NA NA NA -16.995849 NA -17.270506
[79] -17.407459 NA -17.680645 NA NA NA
[85] NA -18.359679 NA NA NA NA
[91] NA -19.167825 NA NA NA -19.702968
[97] -19.836336 NA -20.102594 -20.235490 NA -20.500835
[103] NA NA NA -21.029806 NA NA
[109] -21.425116 NA NA NA -21.950431 NA
[115] NA NA NA NA NA NA
[121] NA NA NA NA NA NA
[127] NA NA -24.034010 -24.163398 -24.292698 NA
[133] NA NA NA NA NA NA
[139] NA NA NA NA NA NA
[145] NA NA NA NA NA NA
[151] NA NA -27.117199 NA NA NA
[157] NA NA NA NA NA NA
[163] NA NA NA NA NA NA
[169] NA -29.277798 NA NA NA NA
[175] NA NA NA NA NA -30.541489
[181] NA NA NA NA NA -31.297439
[187] NA NA -31.674821 NA NA NA
[193] NA NA NA NA NA NA
[199] NA NA NA NA NA NA
[205] NA NA NA NA NA NA
[211] NA NA NA NA NA NA
[217] NA NA NA NA NA NA
[223] NA NA NA NA NA NA
[229] NA NA NA NA -37.171587 NA
[235] NA NA NA NA NA NA
[241] NA NA NA NA NA NA
[247] NA NA NA NA NA NA
[253] NA NA NA -40.021951 NA NA
[259] NA NA NA NA NA NA
[265] NA NA NA NA NA NA
[271] NA NA NA NA NA NA
[277] NA NA NA NA NA NA
[283] NA NA NA NA NA NA
[289] NA NA NA NA NA NA
[295] NA NA NA NA NA NA
[301] NA NA NA NA NA NA
[307] NA NA NA NA NA NA
[313] NA NA NA NA NA NA
[319] NA NA NA NA NA NA
[325] -48.507264 NA NA NA NA NA
[331] NA NA NA NA NA NA
[337] NA NA NA NA NA NA
[343] NA NA NA -51.074698 NA NA
[349] NA NA NA NA NA NA
[355] NA NA NA NA NA NA
[361] NA NA NA NA NA NA
[367] NA NA NA NA NA NA
[373] NA NA NA NA NA NA
[379] NA NA NA NA NA NA
[385] NA NA NA NA NA NA
[391] NA NA NA NA NA NA
[397] NA NA NA NA NA NA
[403] NA NA NA NA NA NA
[409] NA NA NA NA NA NA
[415] NA NA NA NA NA NA
[421] NA NA NA NA NA NA
[427] NA NA NA NA NA NA
[433] NA NA NA NA NA NA
[439] NA NA NA NA NA NA
[445] NA NA -63.355209 NA NA NA
[451] NA NA NA NA NA NA
[457] NA NA NA -64.929415 NA -65.171492
[463] NA NA NA NA NA NA
[469] NA NA NA NA NA NA
[475] NA NA NA NA NA NA
[481] NA NA NA NA NA NA
[487] NA NA NA NA NA NA
[493] NA NA NA NA NA NA
[499] NA NA NA NA NA NA
[505] NA NA NA NA NA NA
[511] NA NA NA NA NA NA
[517] NA NA NA NA NA NA
[523] NA NA NA NA NA NA
[529] NA NA NA NA NA NA
[535] NA NA NA NA NA NA
[541] NA NA NA NA NA NA
[547] NA -75.557026 NA NA NA NA
[553] NA NA NA NA NA NA
[559] NA NA NA NA NA NA
[565] NA NA NA NA NA NA
[571] NA NA NA NA NA NA
[577] NA NA NA NA NA NA
[583] NA NA NA NA NA NA
[589] NA NA NA NA NA NA
[595] NA NA NA NA NA NA
[601] NA NA NA NA NA NA
[607] -82.659672 NA NA NA NA NA
[613] NA NA NA NA NA NA
[619] NA -84.222650 NA NA NA NA
[625] NA NA NA NA NA NA
[631] NA NA NA NA NA NA
[637] NA NA NA NA NA NA
[643] NA NA NA NA NA -87.586858
[649] NA NA NA NA NA NA
[655] NA NA NA NA NA NA
[661] NA NA NA NA NA NA
[667] NA NA NA NA NA NA
[673] NA NA NA NA NA NA
[679] NA NA NA NA NA NA
[685] NA NA NA -92.388061
Notice the 70th term of calc_size
is 688 and the 70th term of sapply(calc_sizes, nb.likelihood)
is -92.38806 (the last numeric value above).
calc_sizes[70]
# [1] 688
sapply(calc_sizes, nb.likelihood)[70]
# [1] -92.3880
To resolve, run along the length of calc_sizes
to assign by 1:87
. Also, consider initializing likelihoods
with a length instead of growing the object after c()
.
likelihoods <- vector(mode="numeric", length=length(calc_sizes))
likelihoods[seq_along(calc_sizes)] <- sapply(calc_sizes, nb.likelihood)
# likelihoods[1:length(calc_sizes)] <- sapply(calc_sizes, nb.likelihood)
Nevertheless, since apply family functions return an object, simple assign directly to the sapply
call without initializing anything.
likelihoods <- sapply(calc_sizes, nb.likelihood)
likelihoods
[1] -1.098612 -11.788381 -2.602690 -3.413620 -30.541489 -4.001407
[7] -8.187640 -8.575276 -6.146104 -13.154588 -4.881330 -7.987619
[13] -4.475865 -6.410490 -17.680645 -8.948901 -31.297439 -31.674821
[19] -5.565697 -11.943435 -9.663029 -8.383385 -5.240275 -6.661805
[25] -15.886160 -5.865802 -9.310881 -7.572668 -24.292698 -7.356445
[31] -13.450466 -9.488087 -8.763676 -7.782825 -87.586858 -9.131222
[37] -10.175841 -10.509013 -9.835872 -11.158148 -13.744013 -19.702968
[43] -12.856183 -7.133302 -75.557026 -21.425116 -11.475373 -10.343221
[49] -20.102594 -21.029806 -10.836219 -11.632377 -82.659672 -20.235490
[55] -37.171587 -12.097586 -15.605646 -24.034010 -10.673316 -29.277798
[61] -20.500835 -16.165367 -6.902190 -12.705964 -15.182243 -17.407459
[67] -19.836336 -63.355209 -64.929415 -92.388061 -51.074698 -24.163398
[73] -12.403344 -16.025922 -84.222650 -21.950431 -19.167825 -40.021951
[79] -27.117199 -17.270506 -65.171492 -48.507264 -14.898089 -15.323743
[85] -13.889967 -16.995849 -18.359679
Online Demo
ifelse() stripping POSIXct attribute from vector of timestamps?
If you look at the way ifelse
is written, it has a section of code that looks like this:
ans <- test
ok <- !(nas <- is.na(test))
if (any(test[ok]))
ans[test & ok] <- rep(yes, length.out = length(ans))[test & ok]
Note that the answer starts off as a logical vector, the same as test. The elements that have test == TRUE
then get assigned to the value of yes
.
The issue here then is with what happens with assignment of an element or elements of a logical vector to be a date of class POSIX.ct. You can see what happens if you do this:
x <- c(TRUE, FALSE)
class(x)
# logical
x[1] <- Sys.time()
class(x)
# numeric
You could get around this by writing:
timestamp <- timestamp + 30
timestamp[is.na(timestamp)] <- fixedDate
You could also do this:
fixedDate = as.POSIXct(strptime("2000-01-01 12:00:00.000000", formatString))
unlist(ifelse(is.na(timestamp), as.list(fixedDate), as.list(timestamp+30)))
This takes advantage of the way the replacement operator [<-
handles a list on the right hand side.
You can also just re-add the class attribute like this:
x <- ifelse(is.na(timestamp), fixedDate, timestamp+30)
class(x) <- c("POSIXct", "POSIXt")
or if you were desperate to do it in one line like this:
`class<-`(ifelse(is.na(timestamp), fixedDate, timestamp+30), c("POSIXct", "POSIXt"))
or by copying the attributes of fixedDate
:
x <- ifelse(is.na(timestamp), fixedDate, timestamp+30)
attributes(x) <- attributes(fixedDate)
This last version has the advantage of copying the tzone
attribute as well.
As of dplyr 0.5.0, you can also use dplyr::if_else
which preserves class in the output and also enforces the same class for the true and false arguments.
Related Topics
Can .Sd Be Viewed from a Browser Within [.Data.Table()
Rmarkdown Error "Attempt to Use Zero-Length Variable Name"
Grouping with Custom Geom Fails - How to Inspect Internal Object from Draw_Panel()
Ggplot2 Y Axis Label Decimal Precision
How to Rotate the X-Axis Labels 90 Degrees in Levelplot
Plotting Multiple Lines from a Data Frame with Ggplot2
R - Count Shiny Download Button Clicks
Names' Attribute Must Be the Same Length as the Vector
Percentage Histogram with Facet_Wrap
Stacked Histograms Like in Flow Cytometry
How to Fit Long Text into Ggplot2 Facet Titles
Change Thickness Median Line Geom_Boxplot()
R Name Colnames and Rownames in List of Data.Frames with Lapply
How to Find the First and Last Occurrences of an Element in a Data.Frame