Related
I want to append data to my list only if it is distinct from previously stored data.
data <- c("A","B","C")
My code so far:
x<- function(...){
data <- ifelse(... %in% data, append(data, ""),append(data, as.character(...)))
return(data)
}
For instance, if I want to append "D," my desired output is:
data
[1] "A" "B" "C" "D"
However, I received this:
data
[1] "A"
x <- c("A","B","C")
y <- c("D", "A")
union(x, y)
# [1] "A" "B" "C" "D"
ifelse function cannot give vector as a result. See ifelse function documentation.
Instead, you should use if - else statement
x<- function(...){
data <- if (... %in% data) {append(data, "")} else {append(data, as.character(...))}
return(data)
}
x("D")
[1] "A" "B" "C" "D"
Here is my solution:
x <- c("A","B","C")
y <- c("D", "A")
unique(c(x, y))
[1] "A" "B" "C" "D"
I created this small example. I want to print some values, for example, B for NA values using the if else statement.
x = c(1,7,NA, 3, NA, NA)
for(i in 1: length(x)){
y = x[i]
if(y == 1){
print("A")
}
else if(y == 'NA'){
print("B")
}
else{
print("C")
}
}
I am getting an error message Error in if (y == 1) { : missing value where TRUE/FALSE needed Why can't I print B for NA values? How to use NA within the if else statement?
The issue is also that == with NA returns NA and not FALSE. Make sure to add a condition to check NA as well. Also, y == 'NA' should be replaced with is.na(y)
for(i in 1:length(x)){
y = x[i]
if(y == 1 & !is.na(y)){
print("A")
}
else if(is.na(y)){
print("B")
}
else{
print("C")
}
}
-output
[1] "A"
[1] "C"
[1] "B"
[1] "C"
[1] "B"
[1] "B"
Or this can be done in a vectorized way
c("C", "B", "A")[1 + is.na(x) + 2 *(x %in% 1)]
#[1] "A" "C" "B" "C" "B" "B"
To avoid repetition, ensure that the first block checks for NA:
x = c(1,7,NA, 3, NA, NA)
for(i in 1: length(x)){
y = x[i]
if(is.na(y)){
print("B")
}
else if(y == 1){
print("A")
}
else{
print("C")
}
}
[1] "A"
[1] "C"
[1] "B"
[1] "C"
[1] "B"
[1] "B"
You can use vectorized way using case_when or nested ifelse -
dplyr::case_when(is.na(x) ~ 'B',
x == 1 ~ 'A',
TRUE ~ 'C')
#[1] "A" "C" "B" "C" "B" "B"
I have a ncol=10, nrow=343 matrix "E" containing letters "a", "b",..,or "f" standing for technologies, where "a" stands for gas. Whenever [row, col]="a" and [row+1,col] !="a" I add resale values for "a" in [row,col] from s_house_gas dim(ncol=10,nrow=10) where the rows are the years like in E. Additionally, resale values for "a" shall be added in E[5,] to account for a resale in the last year.
The code below works, however, I want to add the condition that resale values shall not be added when [row+1] =="d" or "e" but I cannot seem to make it work.
Maybe I have looked at it for too long but I would really appreciate your support here, I feel like I am very close.
HV <- rep.int(0, ncol(E))
R<- rbind(E,HV)
i <- 0
for(col in 1:ncol(R)){
for(row in 1:nrow(R)){
if(R[row,col] == "a" && row <= 10){
i = i+1
R[row,col] = i
} else if (R[row,col] != "a" || row == 11){
i = 0
}
}
}
R <- R[-11,]
Y <- R
for(row in 1:nrow(Y)){
for(col in 1:ncol(Y)){
if(Y[row,col] == "a" || Y[row,col] == "b"|| Y[row,col] == "c" || Y[row,col] == "d"|| Y[row,col] == "e"|| Y[row,col] == "f"){
Y[row,col] = 0
}
}
}
Y <- apply(Y, 2,as.numeric)
L <- rbind(HV,Y,HV)
M <- matrix(0L, nrow = dim(L)[1], ncol = dim(L)[2])
for(col in 1:ncol(L)){
for (row in 2:nrow(L)) {
if(L[row,col] == 0 && L[row-1,col] != 0) {
M[row,col] = row-1-L[row-1,col]
}
}
}
I <- M
N <- matrix(0, nrow = dim(I)[1], ncol = dim(I)[2])
i <- 0
j <- 0
for(row in 2:nrow(I)){
for(col in 1:ncol(I)){
if(I[row,col] != 0){
i = L[row-1,col]
j = M[row,col]
N[row-1,col] = s_house_gas[i, j]
}
}
}
resale_gas <- N[c(-1,-12),]
resale_gas <- matrix(resale_gas, ncol=343, nrow=10)
EDIT
library(xts)
library(stringi)
library(gtools)
t <- c("a","b","c","d","e","f")
E <- t(permutations(6,5, v=t,repeats.allowed=T))
s_house_gas <- 15:11
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] "a" "a" "a" "a" "a" "a" "a" "a"
[2,] "a" "a" "a" "a" "a" "a" "a" "a"
[3,] "a" "a" "a" "a" "a" "a" "a" "a"
[4,] "a" "a" "a" "a" "a" "a" "b" "b"
[5,] "a" "b" "c" "d" "e" "f" "a" "b"
This is what I tried:
HV <- rep.int(0, ncol(E))
R<- rbind(E,HV)
i <- 0
for(col in 1:ncol(R)){
for(row in 1:(nrow(R)-1)){
if(R[row,col] == "a" && R[row+1,col] != "d" && row <= 10 || R[row,col] == "a" && R[row+1,col] != "e" && row <= 10){
i = i+1
R[row,col] = i
} else if (R[row,col] != "a" || row == 11){
i = 0
}
}
}
R <- R[-11,]
Y <- R
for(row in 1:nrow(Y)){
for(col in 1:ncol(Y)){
if(Y[row,col] == "a" || Y[row,col] == "b"|| Y[row,col] == "c" || Y[row,col] == "d"|| Y[row,col] == "e"|| Y[row,col] == "f"){
Y[row,col] = 0
}
}
}
Y <- apply(Y, 2,as.numeric)
L <- rbind(HV,Y,HV)
M <- matrix(0L, nrow = dim(L)[1], ncol = dim(L)[2])
for(col in 1:ncol(L)){
for (row in 2:nrow(L)) {
if(L[row,col] == 0 && L[row-1,col] != 0) {
M[row,col] = row-1-L[row-1,col]
}
}
}
I <- M
N <- matrix(0, nrow = dim(I)[1], ncol = dim(I)[2])
i <- 0
j <- 0
for(row in 2:nrow(I)){
for(col in 1:ncol(I)){
if(I[row,col] != 0){
i = L[row-1,col]
j = M[row,col]
N[row-1,col] = s_house_gas[i, j]
}
}
}
resale_gas <- N[c(-1,-12),]
resale_gas <- matrix(resale_gas, ncol=343, nrow=10)
There are 10 cards written as "S", "T", "A", "T", "I", "S", "T", "I", "C", "S".
After picking ONE card randomly, you put the card back to the original place and mix it. Repeat this until "S","A","T" come out in order.
x<-c("S","T","A","T","I","S","T","I","C","S")
repeat{
print(sample(x,1,replace=TRUE))}
I don't know how to stop when "S","A","T" comes out.
Here is one way
tmp <- c(NA, sample(x, 2, replace = TRUE))
k <- 0
while (!identical(tmp, c("S", "A", "T"))) {
tmp <- c(tmp[-1], sample(x, 1))
k <- k + 1
}
You can use this:
x<-c("S","T","A","T","I","S","T","I","C","S")
pre_last <- NULL
last <- NULL
curr <- NULL
repeat{
curr <- sample(x,1,replace=TRUE)
if(curr == "T")
if(last == "A" && pre_last == "S")
break
pre_last <- last
last <- curr
}
# Result
pre_last
last
curr
Another solution:
s = sapply(1:3,function(i) {sample(x,1,replace=TRUE)})
print(s)
repeat{
if(s[1]=="S" & s[2]=="A" & s[3]=="T")
break
else {
s=s[-1]
s=c(s,(sample(x,1,replace=TRUE)))
print(s)
}
}
You could do this:
set.seed(1)
i <- 1
wanted <- c("S","A","T")
res <- c()
while(TRUE){
r <- sample(x,1,replace = TRUE)
res <- c(res, r)
if(r==wanted[i])
i <- i+1
else i <- 1
if(i==(length(wanted)+1)) break
}
> res
[1] "A" "T" "S" "S" "A" "C" "S" "T" "T" "S" "A" "T"
vec<-c("a", "b", "c", "d")
my task is to extract the second element from the right and left of the key string.
If our key string is "d", if we do
i<-c("d")
vec.1 <- append(vec.1, vec[which(vec == i) + 2])
we get NA. But if we do
i<-c("a")
vec.1 <- append(vec.1, vec[which(vec == i) - 2])
we get "b", "c", "d". Is it possible to consider negative values in subscripts as positions being out of the vector like a positive subscript that exceeds the length of the vector? That way the result will be a NA.
library(Hmisc)
Lag(vec,2)[vec=="d"]
#[1] "b"
Lag(vec,2)[vec=="a"]
#[1] ""
Lag(vec,-2)[vec=="a"]
#[1] "c"
Lag(vec,-2)[vec=="c"]
#[1] ""
I'm sure I could do better, but it's late here. Why not write a small function to do what you want.
myVec <- function(input, match, change) {
temp = which(input == match)
if ((temp + change) <= 0) {
append(NA, input)
} else {
append(input, input[temp + change])
}
}
vec <- c("a", "b", "c", "d")
myVec(vec, "a", -1)
# [1] NA "a" "b" "c" "d"
myVec(vec, "c", -1)
# [1] "a" "b" "c" "d" "b"
myVec(vec, "c", -3)
# [1] NA "a" "b" "c" "d"
myVec(vec, "d", 1)
# [1] "a" "b" "c" "d" NA