Not able to convert dates from string in R - r

Please help. Not sure, what i am doing wrong here. But, the below simple code for converting date from character is not working for me in R. It is giving NA, instead of any values.
x <- c("3-Sep-13","3-Oct-13","10-Nov-2014")
x
# [1] "3-Sep-13" "3-Oct-13" "10-Nov-2014"
class(x)
# [1] "character"
as.Date(x,format="%d-%m-%Y")
# [1] NA NA NA
format(as.Date(x,"%d-%m-%Y"))
# [1] NA NA NA
as.Date(x,format="%Y-%m-%d")
# [1] NA NA NA
format(as.Date(x,"%Y-%m-%d"))
# [1] NA NA NA

Besides what's already mentioned in comments, your character vector is ambiguous.
as.Date(x[1:2], "%d-%b-%y")
[1] "2013-09-03" "2013-10-03"
as.Date(x[3], "%d-%b-%Y")
[1] "2014-11-10"

Related

R Subsetting Specific Value Also Returns NA?

I am just starting out on learning R and came across a piece of code as follows
vec_1 <- c("a","b", NA, "c","d")
# create a subet of all elements which equal "a"
vec_1[vec_1 == "a"]
The result from this is
## [1] "a" NA
Im just curious, since I am subsetting vec_1 for the value "a", why does NA also show up in my results?
This is because the result of anything == NA is NA. Even NA == NA is NA.
Here's the output of vec_1 == "a" -
[1] TRUE FALSE NA FALSE FALSE
and NA is not TRUE or FALSE so when you subset anything by NA you get NA. Check this out -
vec_1[NA]
[1] NA NA NA NA NA
When dealing with NA, R tries to provide the most informative answer i.e. T | NA returns TRUE because it doesn't matter what NA is. Here are some more examples -
T | NA
[1] TRUE
F | NA
[1] NA
T & NA
[1] NA
F & NA
[1] FALSE
R has no way to test equality with NA. In your case you can use %in% operator -
5 %in% NA
[1] FALSE
"a" %in% NA
[1] FALSE
vec_1[vec_1 %in% "a"]
[1] "a"

Ratio of elements of vectors, in a list of vectors

I have a data frame which has a column:
> head(df$lengths,5)
[[1]]
[1] "28"
[[2]]
[1] "33"
[[3]]
[1] "47" "37" "42" "41"
[[4]]
[1] "41" "39" "64" "54"
[[5]]
[1] "45" "22" "23"
I would like to operate on the elements in the vectors, to obtain the ratios of the element(i) to the element(i-k) in each vector. Where a ratio cannot be obtained because element(i-k) has invalid index, the result should be NA. The desired output is like this, where I specified k=1:
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] NA (37/47) (42/37) (41/42)
[[4]]
[1] NA (39/41) (64/39) (54/64)
[[5]]
[1] NA (22/45) (23/22)
as for k=2:
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] NA NA (42/47) (41/37)
[[4]]
[1] NA NA (64/41) (54/39)
[[5]]
[1] NA NA (23/45)
I have little clue on how to approach this, I would think to perform some loops, but in R, it seems complicated. Please advice.
We loop through the list elements (lapply(..), if the length of the list element is 1, we return 'NA' or else divide the next value by the current value and concatenate with NA. We convert to numeric as the original list elements were character class.
lapply(df$lengths, function(x) if(length(x)==1) NA
else c(NA, as.numeric(x[-1])/as.numeric(x[-length(x)])))
Update
We could use the lag/lead function in dplyr/data.table for k values greater than 1.
library(dplyr)
k <- 2
lapply(df$lengths, function(x) {x <- as.numeric(x)
if(length(x)==1) NA
else c(rep(NA,k), na.omit(lead(x,k)))/na.omit(lag(x,k))})
#[[1]]
#[1] NA
#[[2]]
#[1] NA
#[[3]]
#[1] NA NA 0.893617 1.108108
#[[4]]
#[1] NA NA 1.560976 1.384615
#[[5]]
#[1] NA NA 0.5111111
Or without using any packages, we can do with head/tail functions
lapply(lst, function(x) {x <- as.numeric(x)
if(length(x)==1) NA
else c(rep(NA, k), tail(x, -k)/head(x,-k))})

Replacing NAs from onle list by NAs in second list in equal positions in R

here is the problem. I have two lists of vectors. Those vectors have same length in same positions. But there are some NAs in those vectors. Data may looks like
HH
[[1]]
[1] 2 1 5 NA
[[2]]
[1] 2 0 5
[[3]]
[1] NA 1 NA
JJ
[[1]]
[1] 0 5 8 9
[[2]]
[1] NA 1 3
[[3]]
[1] 2 8 3
My goal is: have NAs in equal positions in both lists in all vectors. More exactly, write code, which will find NA in first list, nad replace value by NA in second list in equal position. I succesfully wrote similar function for vector, but i failed here. Can you help me? Here is my code.
D<-NULL
for(j in 1:length(PH)){
+ for(i in 1:length(PH[[j]])){
+ if(is.na(PH[[j]][i])==FALSE){
+ D[[j]][i]=AB[[j]][i]}
+ else{
+ D[[j]][i]=NA}}
+ }
Here's my two cents. Grabbing data from #Colonel's answer,
v1 <- unlist(firstlist)
v2 <- unlist(secondlist)
v1[is.na(v2)] <- NA
relist(v1, firstlist)
#[[1]]
#[1] NA "2" "3" NA
#[[2]]
#[1] "a" NA
You can use Map:
Map(function(u,v) {v[is.na(u)]<-NA;v}, firstlist, secondlist)
Example:
firstlist = list(c(1,2,3,NA), c('a',NA))
secondlist = list(c(NA,22,33,5), c('b','d'))
#[[1]]
#[1] NA 22 33 NA
#[[2]]
#[1] "b" NA

Function for same length of vectors in R

I want to make a function, which should remake list of vectors of different lengths to list of vectors with the same lengths. I made two functions, but the second one does not work well.
My code is:
first function (works well)
delka<-function(x){
delky<<-NULL
for(i in 1:length(x)){
delky[i]<<-length(x[[i]])
}
}
Here I globally made object "delky". Second function is
uprava<- function(x){
stejne<<- NULL
for(i in 1:length(x)){
stejne[[i]]<<-vector(x[[i]], length(max(delky)))
}
}
Where I want to globally make an object "stejne" containing vectors with same lengths. But R answer me an issue
Error in vector(x[[i]], length(max(delky))) : invalid 'mode' argument
Do you have any ideas of what I am doing wrong?
Assuming #RomanLuštrik is correct about what you are trying to do, you can do this much more directly using the following:
lapply(my, `length<-`, max(lengths(my)))
## $a
## [1] 0.8669645 0.9224072 0.2003480 0.9476093 0.1095652 NA
## [7] NA NA NA NA NA
##
## $b
## [1] 0.6679763 0.2742245 0.7726615 0.4247057 0.7274648 0.8218540
## [7] 0.4874759 0.4764729 0.3958279 0.1653358 0.2331573
##
## $c
## [1] 0.71882342 0.92852497 0.75134020 0.53098586 0.17515857
## [6] 0.04997067 0.70350036 NA NA NA
## [11] NA
##
The lengths function was relatively recently introduced, so make sure you are running the most recent version of R.
Assuming you can work on whole lists at a time, and if you want to pad the shorter vectors with NAs, here's one way.
my <- list(a = runif(5),
b = runif(11),
c = runif(7))
maxl <- max(sapply(my, length))
sapply(my, FUN = function(x, ml) {
difference <- ml - length(x)
c(x, rep(NA, difference))
}, ml = maxl, simplify = FALSE)
$a
[1] 0.91906470 0.68651070 0.07317576 0.52985130 0.27916889 NA NA NA NA NA NA
$b
[1] 0.86384953 0.79707167 0.88226627 0.91590091 0.03181455 0.86493584 0.89597354 0.80890065 0.92418156 0.72947596 0.13847751
$c
[1] 0.2576621 0.6512487 0.5806530 0.8782730 0.0262019 0.1000885 0.5245472 NA NA NA NA
in another representation
sapply(my, FUN = function(x, ml) {
difference <- ml - length(x)
c(x, rep(NA, difference))
}, ml = maxl)
a b c
[1,] 0.91906470 0.86384953 0.2576621
[2,] 0.68651070 0.79707167 0.6512487
[3,] 0.07317576 0.88226627 0.5806530
[4,] 0.52985130 0.91590091 0.8782730
[5,] 0.27916889 0.03181455 0.0262019
[6,] NA 0.86493584 0.1000885
[7,] NA 0.89597354 0.5245472
[8,] NA 0.80890065 NA
[9,] NA 0.92418156 NA
[10,] NA 0.72947596 NA
[11,] NA 0.13847751 NA

Match number within list of different length vectors

I want to match a number within a list containing vector of different lengths. Still my solution (below) doesn't match anything beyond the first item of each vector.
seq_ <- seq(1:10)
list_ <- list(seq_[1:3], seq_[4:7], seq_[8:10])
list_
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 4 5 6 7
#
# [[3]]
# [1] 8 9 10
but
for (i in seq_) {
print(match(i,list_))
}
# [1] 1
# [1] NA
# [1] NA
# [1] 3
# [1] NA
# [1] NA
# [1] NA
# [1] NA
# [1] NA
# [1] NA
In the general case, you probably will be happier with which, as in
EDIT: rewrote to show the full looping over values.
seq_ <- seq(1:10)
list_ <- list(seq_[1:3], seq_[4:7], seq_[8:10])
matchlist<-list(length=length(list_))
for( j in 1:length(list_)) {
matchlist[[j]] <- unlist(sapply(seq_, function(k) which(list_[[j]]==k) ))
}
That will return the locations of all matches. It's probably more clear what's happening if you create an input like my.list <- list(sample(1:10,4,replace=TRUE), sample(1:10,7,replace=TRUE))

Resources