I am new to R. I want to carry out a simulation starting at Period 0. That works quite well using vectors, but they all start at position 1.
Is there a way to change that? Or an alternative?
Thanks a lot!
Serijoscha
Use the Oarray package with offset = 0
library(Oarray)
vec <- Oarray(1:10, offset = 0)
vec[0]
#[1] 1
Related
So I am working on a data frame on a column that should say hours of sleep per night however using difftime() function has given values which show the number of hours sleep in negative values for some and the number of hours awake in positive values for others. I want to subtract 24 from just those who are above 0 (non negative numbers) so I have done:
data$Sleep.time <- with(data = data,
difftime(Bed.time, Waking.up.time, units = "hours"))
data$Sleep.time <- as.numeric(data$Sleep.time)
data$subtract <- (24)
data$Sleep.time <- if (data$Sleep.time>0) {data$Sleep.time - data$subtract}
So this just takes 24 away from all of the values so my values that are already negative are completely wrong. I'm not quite sure how to use the if function so this works properly any help would be great!
if is not vectorized i.e. it expects a logical expression with length 1. The 'Sleep.time' column will have more than one element. We may either use ifelse or create an index and use it to subtract and assign
i1 <- data$Sleep.time> 0
data$Sleep.time[i1] <- data$Sleep.time[i1] - data$subtract[i1]
You could try using ifelse
something like this
data$Sleep.time <- ifelse(data$Sleep.time > 0, data$Sleep.time - 24, data$Sleep.time)
Syntax: ifelse(condition, if true, else) returns a vector if the condition is applied on a vector.
Hope it helps and this is vectorized, so much faster than a loop.
I have a list of increasing year values that occasionally has breaks in it and I want to create a grouping value for each unbroken sequence. Think of a vector like this one (missing 2005,2011):
x <- c(2001,2002,2003,2004,2006,2007,2008,2009,2010,2013,2014,2015,2016)
I would like to produce an equal length vector that numbers every value in a run with the same index to end up with something like this.
[1] 1 1 1 1 2 2 2 2 2 3 3 3 3
I would like to do this using best R practices so I am trying to avoid falling back to a for loop but I am not sure how to get from Vector A to Vector B. Does anyone have any suggestions?
Some things I know I can do:
I can flag the record before or after a gap as true with an ifelse
I can get the index of when the counter should change by wrapping that in a which statement
This is the code to do each
ifelse(!is.na(lag(x)) & x == lag(x)+1, FALSE, TRUE)
which(ifelse(!is.na(lag(x)) & x == lag(x)+1, FALSE, TRUE))
I think there a couple solutions to this problem. One as d.b posted in the comment above that will produce a sequence that increments every time there is a break in the sequence.
cummax(c(1, diff(x)))
There is a similar solution that I chose to use with ifelse() flagging breaks and cumsum(). I chose this solution because additional information,like other vectors, can be included in the decision and diff seems to have problems with very erratic up and down values.
cumsum(ifelse(!is.na(lag(x)) & x == lag(x) + 1, FALSE, TRUE))
so I have a loop that finds the position in the matrix where there is the largest difference in consecutive elements. For example, if thematrix[8] and thematrix[9] have the largest difference between any two consecutive elements, the number given should be 8.
I made the loop in a way that it will ignore comparisons where one of the elements is NaN (because I have some of those in my data). The loop I made looks like this.
thenumber = 0 #will store the difference
for (i in 1:nrow(thematrix) - 1) {
if (!is.na(thematrix[i]) & !is.na(thematrix[i + 1])) {
if (abs(thematrix[i] - thematrix[i + 1]) > thenumber) {
thenumber = i
}
}
}
This looks like it should work but whenever I run it
Error in if (!is.na(thematrix[i]) & !is.na(thematrix[i + 1])) { :
argument is of length zero
I tried this thing but with a random number in the brackets instead of i and it works. For some reason it only doesn't work when I use the i specified in the beginning of the for-loop. It doesn't recognize that i represents a number. Why doesn't R recognize i?
Also, if there's a better way to do this task I'd appreciate it greatly if you could explain it to me
You are pretty close but when you call i in 1:nrow(thematrix) - 1 R evaluates this to make i = 0 which is what causes this issue. I would suggest either calling i in 1:nrow(thematrix) or i in 2:nrow(thematrix) - 1 to start your loop at i = 1. I think your approach is generally pretty intuitive but one suggestion would be to frequently use the print() function to evaluate how i changes over the course of your function.
The issue is that the : operator has higher precedence than -; you just need to use parentheses around (nrow(thematrix)-1). For example,
thematrix <- matrix(1:10, nrow = 5)
##
wrong <- 1:nrow(thematrix) - 1
right <- 1:(nrow(thematrix) - 1)
##
R> wrong
#[1] 0 1 2 3 4
R> right
#[1] 1 2 3 4
Where the error message is coming from trying to access the zero-th element of thematrix:
R> thematrix[0]
integer(0)
The other two answers address your question directly, but I must say this is about the worst possible way to solve this problem in R.
set.seed(1) # for reproducible example
x <- sample(1:10,10) # numbers 1:10 in random order
x
# [1] 3 4 5 7 2 8 9 6 10 1
which.max(abs(diff(x)))
# [1] 9
The diff(...) function calculates sequential differences, and which.max(...) identifies the element number of the maximum value in a vector.
I want to create an R vector with two repeat elements. A length of the array is 200.
But each element can be either 'x' or 'y'.
an element can be x or y with equal chance.
Is there any grammatical function in R to do above task?
Please someone help.
A possible way to do it is to use rbinom. Step by step, generate first a vecotr of 0 and 1, then change it into x and y:
vec = ifelse(rbinom(200, 1, 0.5)==0,"x","y"))
We need a little bit more information to be helpful, but if you want a vector of 200 values, 100 x's and 100 y's, then just do this:
t <- rep(c('X','Y'), 100)
If you want this in a random order:
t <- sample(t)
i need some advise for the following problem:
I have a dataframe with two columns, one containing the date, the other the frequency of a an event.
Now i want to add a third column to this dataframe, wich should contain some binary data: 1 for days with a frequency of 100 and higher, 0 for the lower ones.
Has anyone an idea how to do this in a smart way (i'm affraid of writing it by hand;-)? Thanks for your answer in advance!
data$newcol = as.integer(data$freq >= 100)
alternatively
data$newcol = ifelse(data$freq >= 100, 1, 0)
alternatively
data$newcal = 0
data$newcol[data$freq >= 100] = 1
df$freq.gt.100 = as.integer(df$freq >= 100)
The bit inside brackets evaluates to TRUE or FALSE which can be converted to 1 or 0 via as.integer.
There's nothing to be "afraid" of: you can test the right-hand side of the expression on its own to check it works and only when you are happy with this do you add it as a new column to the original data.
EDIT: didn't see the above answer as I was creating this one and had a call to take!