Suppose I have this list:
my_variable <- list()
x <- c(1,2,3,4)
y <- c(4,5,7,3)
for ( i in 1:4){
my_variable[[i]] <- x[i]*y[i]+2
}
Then I will get this:
[[1]]
[1] 6
[[2]]
[1] 12
[[3]]
[1] 23
[[4]]
[1] 14
How to name the element of the output, like this:
> my_variable
First_result
[1] 6
Second_result
[1] 12
and so on.
You could do it with the paste0 and names
# So first you define vector of names:
names1 <- c("First","Second","Third","Fourth")
# And second you paste them to your list
names(my_variable) <- paste0(names1,"_result", sep = "")
#And the output
$First_result
[1] 6 12 23 14
$Second_result
[1] 6 12 23 14
$Third_result
[1] 6 12 23 14
$Fourth_result
[1] 6 12 23 14
Related
Let's assume I have this vector v:
v = seq(1,30,1)
I write this simple loop:
for(i in v) {
print(i)
}
However, I would like to write a loop that gives me, in time, 1:2, 3:4, 5:6, 7:8, etc. I would then get:
[1] 1,2
[1] 3,4
[1] 5,6
[1] 7,8
...
Can anyone help me?
Thanks!
Maybe you can generate v with step of 2.
v = seq(1,30,2)
for(i in v) {
cat(paste(i, i + 1, sep = ','), '\n')
}
#1,2
#3,4
#5,6
#7,8
#9,10
#11,12
#13,14
#...
If you want to keep your approach, try this:
for(i in v[-length(v)]) {
print(c(i, i+1))
}
[1] 1 2
[1] 2 3
[1] 3 4
...
Adding i to a subset.
for(i in v) {
print(v[0:1 + i])
}
# [1] 1 2
# [1] 2 3
# [1] 3 4
# [1] ...
Alternatively you could also consider this:
cbind(v[-length(v)], v[-1])
# [,1] [,2]
# [1,] 1 2
# [2,] 2 3
# [3,] 3 4
# [4,] 4 5
# [5,] 5 6
# [6,] ...
You need to update the print command and use the method range
https://www.w3schools.com/python/ref_func_range.asp
for i in range(0,len(v)-1,2):
print(str(v[i])+","+str(v[i+1]))
In this way you should get
1,2
3,4
5,6
7,8
...
Try this
> for(i in v) if (i%%2) print(c(i,i+1))
[1] 1 2
[1] 3 4
[1] 5 6
[1] 7 8
[1] 9 10
[1] 11 12
[1] 13 14
[1] 15 16
[1] 17 18
[1] 19 20
[1] 21 22
[1] 23 24
[1] 25 26
[1] 27 28
[1] 29 30
Simple problem, given a list:
main_list <- list(1:3,
4:6,
7:9,
10:12,
13:15)
main_list
# [[1]]
# [1] 1 2 3
# [[2]]
# [1] 4 5 6
# [[3]]
# [1] 7 8 9
# [[4]]
# [1] 10 11 12
# [[5]]
# [1] 13 14 15
I want to split the list into multiple lists where I break up the original one into lists each of length x. So if I said x = 2, I would get 3 lists of length 2, 2 and the leftover 1:
target <- list(list(1:3,
4:6),
list(7:9,
10:12),
list(13:15))
target
# [[1]]
# [[1]][[1]]
# [1] 1 2 3
# [[1]][[2]]
# [1] 4 5 6
# [[2]]
# [[2]][[1]]
# [1] 7 8 9
# [[2]][[2]]
# [1] 10 11 12
# [[3]]
# [[3]][[1]]
# [1] 13 14 15
Something like:
my_split <- function(listtest, x) {
split(listtest, c(1:x))
}
target <- my_split(main_list, 2)
Thanks
here is an option with gl
split(main_list, as.integer(gl(length(main_list), 2, length(main_list))))
It can be converted to a custom function
f1 <- function(lstA, n) {
l1 < length(lstA)
split(lstA, as.integer(gl(l1, n, l1)))
}
EDIT: no conditional logic needed. Just use split() with c() and rep():
my_split <- function(l, x){
l_length <- length(l)
l_div <- l_length / x
split(l, c(rep(seq_len(l_div), each = x), rep(ceiling(l_div), l_length %% x)))
}
my_split(main_list, 2)
I am quite a newbie to the r language i wanted to read the following input but Ihave no idea how to proceed:
m n
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
I wanted to read the following input into 6 categories
m
n
c(1,5,9,13)
c(2,6,10,14)
c(3,7,11,15)
c(4,8,12,16)
I tried the following code but it doesn't seem to work
f <- file("stdin")
r <- file("stdin")
data1 = scan(file = r,skip = 1)
data1 <- split(data1, " ")
data2 = scan(file = f ,nlines =1)
data2 <- split(data2, " ")
o1 = data2[1]
o2 = data2[2]
It always seems to give
"Read 0 items"
for data2.
Use read.table twice where Lines is given in the Note at the end.
mn <- read.table(text = Lines, nrows = 1, as.is = TRUE)
DF <- read.table(text = Lines, skip = 1)
giving:
mn
## V1 V2
## 1 m n
mn[[1]]
## [1] "m"
mn$V1 # same
## [1] "m"
DF
## V1 V2 V3 V4
## 1 1 2 3 4
## 2 5 6 7 8
## 3 9 10 11 12
## 4 13 14 15 16
DF[[1]]
## [1] 1 5 9 13
DF$V1 # same
## [1] 1 5 9 13
A list made up of the 6 components is:
unname( c(mn, DF) )
## [[1]]
## [1] "m"
##
## [[2]]
## [1] "n"
##
## [[3]]
## [1] 1 5 9 13
##
## [[4]]
## [1] 2 6 10 14
##
## [[5]]
## [1] 3 7 11 15
##
## [[6]]
## [1] 4 8 12 16
scan
If you prefer to use scan, as in the question, then assuming that the lines all have the same number of fields except for the first line, get the field counts, one per line, into counts and then use scan using those numbers:
counts <- count.fields(textConnection(Lines))
c( scan(text = Lines, what = "", nmax = counts[1], quiet = TRUE),
scan(text = Lines, what = as.list(numeric(counts[2])), skip = 1, quiet = TRUE) )
## [[1]]
## [1] "m"
##
## [[2]]
## [1] "n"
##
## [[3]]
## [1] 1 5 9 13
##
## [[4]]
## [1] 2 6 10 14
##
## [[5]]
## [1] 3 7 11 15
##
## [[6]]
## [1] 4 8 12 16
Note
Assume the input is:
Lines <- "m n
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16"
Problem:
I have a list of two lists of three vectors. I would like to remove the zero vector from each sublist.
Example:
x <- list(x1=c(0,0,0), x2=c(3,4,5), x3=c(45,34,23))
y <- list(y1=c(2,33,4), y2=c(0,0,0), y3=c(4,5,44))
z <- list(x, y)
Try:
I tried this:
res <- lapply(1:2, function(i) {lapply(1:3, function(j) z[[i]][[j]][z[[i]][[j]] != 0])})
Which gave me this:
> res
[[1]]
[[1]][[1]]
numeric(0)
[[1]][[2]]
[1] 3 4 5
[[1]][[3]]
[1] 45 34 23
[[2]]
[[2]][[1]]
[1] 2 33 4
[[2]][[2]]
numeric(0)
[[2]][[3]]
[1] 4 5 44
Problem with the output:
I do not want numeric(0).
Expected output:
x= list(x2, x3)
y=list(y1, y3)
Any idea, please?
You can try a tidyverse if the nested list structure is not important
library(tidyverse)
z %>%
flatten() %>%
keep(~all(. != 0))
$x2
[1] 3 4 5
$x3
[1] 45 34 23
$y1
[1] 2 33 4
$y3
[1] 4 5 44
Given your structure of list of lists I would go with the following:
filteredList <- lapply(z, function(i) Filter(function(x) any(x != 0), i))
x <- filteredList[[1]]
y <- filteredList[[2]]
x
##$`x2`
##[1] 3 4 5
##$x3
##[1] 45 34 23
y
##$`y1`
##[1] 2 33 4
##$y3
##[1] 4 5 44
define z as
z <- c(x, y)
# z <- unlist(z, recursive = F) if you cannot define z by yourself.
then use:
z[sapply(z, any)]
#$`x2`
#[1] 3 4 5
#$x3
#[1] 45 34 23
#$y1
#[1] 2 33 4
#$y3
#[1] 4 5 44
Please note:
As in the tradition of lang C. Every integer/ numeric != 0 will be casted to TRUE. So in this task we can use this logic. ?any will eval FALSE if all values are 0.
Or:
x <- list(x1=c(0,0,0), x2=c(3,4,5), x3=c(45,34,23))
y <- list(y1=c(2,33,4), y2=c(0,0,0), y3=c(4,5,44))
z <- list(x, y)
lapply(z, function(a) a[unlist(lapply(a, function(b) !identical(b, rep(0,3))))])
#[[1]]
#[[1]]$`x2`
#[1] 3 4 5
#
#[[1]]$x3
#[1] 45 34 23
#
#
#[[2]]
#[[2]]$`y1`
#[1] 2 33 4
#
#[[2]]$y3
#[1] 4 5 44
with purrr it can be really compact
library(purrr)
map(z, keep ,~all(.!=0))
# [[1]]
# [[1]]$x2
# [1] 3 4 5
#
# [[1]]$x3
# [1] 45 34 23
#
#
# [[2]]
# [[2]]$y1
# [1] 2 33 4
#
# [[2]]$y3
# [1] 4 5 44
If it wasn't for the annoying warnings we could do just map(z, keep , all)
Imagine, I have list of two levels:
lll <- list()
lll[[1]] <- list(1:10, 1:5, 1:2)
lll[[2]] <- list(10:20, 20:30)
lll
[[1]]
[[1]][[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[1]][[2]]
[1] 1 2 3 4 5
[[1]][[3]]
[1] 1 2
[[2]]
[[2]][[1]]
[1] 10 11 12 13 14 15 16 17 18 19 20
[[2]][[2]]
[1] 20 21 22 23 24 25 26 27 28 29 30
I want calculate means of these sequences. I have written a little function, which works fine:
func <- function(list.list){
lapply(1:length(list.list), function(i) mean(list.list[[i]]))
}
lapply(lll, func)
I don't like in this function, that I have to use anonymous function.
It gets even more complicated when I have list of 3 levels.
Maybe you know better ways to make calculations in which anonymous function would not be included? Should I use higher-order functions (Map, Reduce)?
I know how to write for cycle, but in this case it isn't an option.
Here's a possible solution (using rapply = recursive apply) working at any level of depth :
lll <- list()
lll[[1]] <- list(1:10, 1:5, 1:2)
lll[[2]] <- list(10:20, 20:30)
res <- rapply(lll,mean,how='replace')
> res
[[1]]
[[1]][[1]]
[1] 5.5
[[1]][[2]]
[1] 3
[[1]][[3]]
[1] 1.5
[[2]]
[[2]][[1]]
[1] 15
[[2]][[2]]
[1] 25
Setting argument how='unlist' you will get :
res <- rapply(lll,mean,how='replace')
> res
[1] 5.5 3.0 1.5 15.0 25.0