Given a word I need to find the decimal values of each letter in that word and store it in an array.
I used strtoi function to achieve this. But later found out below two functions which are supposed to give same output are giving different result. Can anyone explain why?
1st attempt
> strtoi("d",16L)
[1] 13
2nd attempt
> strtoi(charToRaw("d"),16L)
[1] 100
And what does 16L in the base of srtoi mean? I am fairly new to Dec, Hex, Oct representation of ASCII characters. So please share some information about it.
For illustration purposes only:
library(purrr)
library(tibble)
input_str <- "Alphabet."
charToRaw(input_str) %>%
map_df(~data_frame(letter=rawToChar(.),
hex_value=toString(.),
decimal_value=as.numeric(.)))
## # A tibble: 9 × 3
## letter hex_value decimal_value
## <chr> <chr> <dbl>
## 1 A 41 65
## 2 l 6c 108
## 3 p 70 112
## 4 h 68 104
## 5 a 61 97
## 6 b 62 98
## 7 e 65 101
## 8 t 74 116
## 9 . 2e 46
Since what you need to do can be done all in base R:
as.numeric(charToRaw(input_str))
## [1] 65 108 112 104 97 98 101 116 46
You can also do as.integer() vs as.numeric() if you just need/want integers.
Related
Thanks to #akrun, I could run my previous question about merging and creating tables with loop. Merge and create tables using a loop
However, because my laptop only has 16GB of RAM, I couldn't run the large dataset using the code. So, instead of merging 100 times, I decided to separate the process, and do it step by step using a for-loop.
I was going to create 20 lists of data using for loop, but then I couldn't find a way to make this happen.
To be specific, I would run the following 20 lines of code manually without using a for loop.
list1 <- mget(paste0("", 1:5))
list2 <- mget(paste0("", 6:10))
list3 <- mget(paste0("", 11:15))
list4 <- mget(paste0("", 16:20))
list5 <- mget(paste0("", 21:25))
...
list20 <- mget(paste0("", 96:100))
How would I write for loop in this case?
I tried to find a way to do this (for example as below), but I am getting an error.
for(i in 1:20){
list[i] <- mget(paste0("",5*i-4:5*i))
}
Thanks in advance for all your help!
There are multiple ways to create the list. Either use split with %/%
fulllst <- lapply(split(as.character(1:100), (1:100-1) %/% 5 + 1), mget)
Or use the same code in OP's post by wrapping the code with () to avoid evaluation based on precedence of operators
# create an empty list to store the output
lstout <- vector('list', 20)
# loop over the sequence and add the `()` for `(5* i- 4)` and similarly for (5*i)
for(i in 1:20)
lstout[[i]] <- mget(as.character((5 *i -4):(5*i)))
Use print to find the difference
> for(i in 1:20) print((5 *i -4):(5*i))
[1] 1 2 3 4 5
[1] 6 7 8 9 10
[1] 11 12 13 14 15
[1] 16 17 18 19 20
[1] 21 22 23 24 25
[1] 26 27 28 29 30
[1] 31 32 33 34 35
[1] 36 37 38 39 40
[1] 41 42 43 44 45
[1] 46 47 48 49 50
[1] 51 52 53 54 55
[1] 56 57 58 59 60
[1] 61 62 63 64 65
[1] 66 67 68 69 70
[1] 71 72 73 74 75
[1] 76 77 78 79 80
[1] 81 82 83 84 85
[1] 86 87 88 89 90
[1] 91 92 93 94 95
[1] 96 97 98 99 100
> for(i in 1:20) print(5 *i -4:5*i)
[1] 1 0
[1] 2 0
[1] 3 0
[1] 4 0
[1] 5 0
[1] 6 0
[1] 7 0
[1] 8 0
[1] 9 0
[1] 10 0
[1] 11 0
[1] 12 0
[1] 13 0
[1] 14 0
[1] 15 0
[1] 16 0
[1] 17 0
[1] 18 0
[1] 19 0
[1] 20 0
ie. if we don't use the () the evaluation will be
i <- 1
(5 * i) - (4:5 * i)
[1] 1 0
# instead of
(5 * i -4):(5 * i)
[1] 1 2 3 4 5
The operator precendence is showed in ?Syntax
:: ::: access variables in a namespace
$ # component / slot extraction
[ [[ indexing
^ exponentiation (right to left)
- + unary minus and plus
: sequence operator
%any% |> special operators (including %% and %/%)
* / multiply, divide
+ - (binary) add, subtract
....
It works that it iterates over word, but the variable "word" contains a word, instead of the number (position) of that word in the row. For example, in the first row, 'yzi' has number 1, and 'runner' has number 3. Can anyone help?
Are you looking for this?
lapply(strsplit(output$text, ' '), function(x) seq_along(x)^2)
#[[1]]
# [1] 1 4 9 16 25 36 49 64 81 100 121 144 169 196
#[[2]]
# [1] 1 4 9 16 25 36 49 64 81 100 121 144 169 196
#[[3]]
# [1] 1 4 9 16 25 36 49 64 81 100 121 144 169
#[[4]]
# [1] 1 4 9 16 25 36 49 64 81 100
#...
#...
Or in a loop -
for(row in 1:nrow(output)){
list=strsplit(output$text[row], " ")[[1]]
for(i in seq_along(list)){
print(i^2)
}
}
We can use map
library(purrr)
map(strsplit(output$text, ' '), ~ seq_along(.x)^2)
I am having difficulties trying to order a list element-wise by decreasing order...
I have a ByPos_Mindex object or a list of 1000 IRange objects (CG_seqP) from
C <- vmatchPattern(CG, CPGi_Seq, max.mismatch = 0, with.indels = FALSE)
IRanges object with 27 ranges and 0 metadata columns:
start end width
<integer> <integer> <integer>
[1] 1 2 2
[2] 3 4 2
[3] 9 10 2
[4] 27 28 2
[5] 34 35 2
... ... ... ...
[23] 189 190 2
[24] 207 208 2
[25] 212 213 2
[26] 215 216 2
[27] 218 219 2
length(1000 of these IRanges)
I then change this to a list of only the start integers (which I want)
CG_SeqP <- sapply(C, function(x) sapply(as.vector(x), "[", 1))
[[1]]
[1] 1 3 9 27 34 47 52 56 62 66 68 70 89 110 112
[16] 136 140 146 154 160 163 178 189 207 212 215 218
(1000 of these)
The Problem happens when I try and order the list of elements using
CG_SeqP <- sapply(as.vector(CG_SeqP),order, decreasing = TRUE)
I get a list of what I think is row numbers so if the first IRAnge object is 27 I get this...
CG_SeqP[1]
[[1]]
[1] 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8
[21] 7 6 5 4 3 2 1
So the decreasing has worked but not for my actual list of elements>?
Any suggestions, thanks in advance.
Order returns order of the sequence not the actual elements of your vector, to extract it let us look at a toy example (I am following your idea here) :
set.seed(1)
alist1 <- list(a = sample(1:100, 30))
So, If you print alist1 with the current seed value , you will have below results:
> alist1
$a
[1] 99 51 67 59 23 25 69 43 17 68 10 77 55 49 29 39 93 16 44
[20] 7 96 92 80 94 34 97 66 31 5 24
Now to sort them either you use sort function or you can use order, sort just sorts the data, whereas order just returns the order number of the elements in a sorted sequence. It doesn't return the actual sequence, it returns the position. Hence we need to put those positions in the actual vector using square notation brackets to get the right sorted outcome.
lapply(as.vector(alist1),function(x)x[order(x, decreasing = TRUE)])
I have used lapply instead of sapply just to enforce the outcome as a list. You are free to choose any command basis your need
Will return:
#> lapply(as.vector(alist1),function(x)x[order(x, decreasing = TRUE)])
#$a
# [1] 99 97 96 94 93 92 80 77 69 68 67 66 59 55 51 49 44 43 39
#[20] 34 31 29 25 24 23 17 16 10 7 5
I hope this clarifies your doubt. Thanks
I have a long list of numbers, e.g.
set.seed(123)
y<-round(runif(100, 0, 200))
And I would like to store in column y the number of values that exceed each value in column x of a data frame:
df <- data.frame(x=seq(0,200,20))
I can compute the numbers manually, like this:
length(which(y>=20)) #93 values exceed 20
length(which(y>=40)) #81 values exceed 40
etc. I know I can use a for-loop with all values of x, but is there a more elegant way?
I tried this:
df$y <- length(which(y>=df$x))
But this gives a warning and does not give me the desired output.
The data frame should look like this:
df
x y
1 0 100
2 20 93
3 40 81
4 60 70
5 80 61
6 100 47
7 120 40
8 140 29
9 160 19
10 180 8
11 200 0
You can compare each value of df$x against all value of y using sapply
sapply(df$x, function(a) sum(y>a))
#[1] 99 93 81 70 61 47 40 29 18 6 0
#Looking at your output, maybe you want
sapply(df$x, function(a) sum(y>=a))
#[1] 100 93 81 70 61 47 40 29 19 8 0
Here's another approach using outer that allows for element wise comparison of two vectors
rowSums(outer(df$x,y, "<="))
#[1] 100 93 81 70 61 47 40 29 19 8 0
Yet one more (from alexis_laz's comment)
length(y) - findInterval(df$x, sort(y), left.open = TRUE)
# [1] 100 93 81 70 61 47 40 29 19 8 0
> Cases <- c(4,46,98,115,88,34)
> Cases
[1] 4 46 98 115 88 34
> str(Cases)
num [1:6] 4 46 98 115 88 34
I want to name row as "total.cases" and I got error attempt to set rownames with no dimensions.please see expected the output to be as follow
total.cases 4 46 98 115 88 34
Your problem is that Cases as you define it is an atomic vector. There is no concept of rows or columns.
I think you probably want a list
Cases <- list(total.cases = c(4,46,98,115,88,34))
Cases
## $total.cases
## [1] 4 46 98 115 88 34
str(Cases)
## List of 1
## $ total.cases: num [1:6] 4 46 98 115 88 34
Do you want to print the output in a particular way or do you actually want rownames?
To print Cases how you want, you could just use:
> cat("total.cases ",Cases,"\n")
total.cases 4 46 98 115 88 34
To assign a rowname, you need to actually have rows first. A vector (like Cases) doesn't have any rows or columns as dimensions. You could however convert to a matrix though:
> matrix(Cases,nrow=1,dimnames=list("total.cases",1:length(Cases)))
1 2 3 4 5 6
total.cases 4 46 98 115 88 34