How to Get the Nth Element of Each Item of a List, Which Is Itself a Vector of Unknown Length

How to get the nth element of each item of a list, which is itself a vector of unknown length

We can create a function using sapply

fun1 <- function(lst, n){
sapply(lst, `[`, n)
}
fun1(l, 1)
#[1] 1 3 5 6

fun1(l, 2)
#[1] 2 4 NA 7

Extract vector from list in R

you can try this when you want other values than NA. Otherwise use the answer of
@docendo discimus

sapply(list(a=1:2,b=1:3), function(x,y){
if(length(x) < y) 0 else x[y]},3)
a b
0 3

You can also try a tidyverse solution

library(tidyverse)
map_int(list(a=1:2,b=1:3), function(x) coalesce(x[3],0L))
a b
0 3

How to get last subelement of every element of a list?

We can use lapply and tail:

x <- list(a = 1:5, b = 1:10, d = 9:11)
last_elems <- lapply(x, tail, n = 1L)

As pointed out in the comments, to obtain a numeric vector instead of a one-element list, vapply is a good choice:

last_elems <- vapply(x, tail, n = 1L, FUN.VALUE = numeric(1))

R list get first item of each element

sapply(d, "[[", 1) should do the trick.

A bit of explanation:

sapply: iterates over the elements in the list

[[: is the subset function. So we are asking sapply to use the subset function on each list element.

1 : is an argument passed to "[["

It turns out that "[" or "[[" can be called in a traditional manner which may help to illustrate the point:

x <- 10:1
"["(x, 3)
# [1] 8

How to get the second to last element in a Vector in R

It seems you want to leave one element from the vector A. You can simply write B=tail(A,-1)
where -1 leaves the first element.

Function that multiplies each element of one list with four elements of second list in a loop to get a new list

For e.g.

a = range(40)
b = range(10)

Simplest:

[x * b[i//4] for i, x in enumerate(a)]

More functional:

# from https://docs.python.org/3/library/itertools.html#itertools-recipes
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)

[a1 * b1 for a4, b1 in zip(grouper(a, 4), b) for a1 in a4]

Cannot Construct Fixed Length Vector from List

You need to write fromList so that it can provide a Vec n a of some unknown (at compile time) n instead of for any given n. One way to do this is to rewrite it in continuation-passing style:

{-# LANGUAGE RankNTypes #-}

fromList :: [a] -> (forall n. Vec n a -> r) -> r
fromList (x:xs) cont = fromList xs (\v -> cont (x :+ v))
fromList [] cont = cont VNil

In your example, the compiler is complaining because n is a "rigid type variable"—in other words, fromList has an implicit forall n at the beginning of its type, so callers of fromList can provide fromList with an arbitrary n and expect it to work. That's not what you want, because you want fromList to compute the n from the length of the list, not receive the n from its caller.

So the solution is to have fromList provide the n, by calling a continuation which itself takes n as a forall type variable.

In mathematical terms, you want n to be existentially quantified—that there exists some n for which fromList produces a Vec n a from a given input—not universally quantified—that for all n, fromList will produce a Vec n a from a given input.

There are other ways than continuation passing to encode existential quantification in Haskell. Here's an alternative:

data SomeVec a = forall n. SomeVec (Vec n a)

fromList' :: [a] -> SomeVec a
fromList' (x:xs) = case (fromList' xs) of (SomeVec v) -> SomeVec (x :+ v)
fromList' [] = SomeVec VNil

This approach may be cleaner in some cases, but may require you to implement a bunch of instances for SomeVec that are already implemented for Vec.

(You may also notice that this isn't really a fundamentally different approach; fromList' xs = fromList xs SomeVec.)

For more information, a search for "existential types in Haskell" should turn up plenty of further leads.

How do I get an empty list of any size in Python?

If by "array" you actually mean a Python list, you can use

a = [0] * 10

or

a = [None] * 10

Finding and replacing elements in a list

You can use the built-in enumerate to get both index and value while iterating the list. Then, use the value to test for a condition and the index to replace that value in the original list:

>>> a = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1]
>>> for i, n in enumerate(a):
... if n == 1:
... a[i] = 10
...
>>> a
[10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]

How to correctly use lists?

Just to address the last part of your question, since that really points out the difference between a list and vector in R:

Why do these two expressions not return the same result?

x = list(1, 2, 3, 4); x2 = list(1:4)

A list can contain any other class as each element. So you can have a list where the first element is a character vector, the second is a data frame, etc. In this case, you have created two different lists. x has four vectors, each of length 1. x2 has 1 vector of length 4:

> length(x[[1]])
[1] 1
> length(x2[[1]])
[1] 4

So these are completely different lists.

R lists are very much like a hash map data structure in that each index value can be associated with any object. Here's a simple example of a list that contains 3 different classes (including a function):

> complicated.list <- list("a"=1:4, "b"=1:3, "c"=matrix(1:4, nrow=2), "d"=search)
> lapply(complicated.list, class)
$a
[1] "integer"
$b
[1] "integer"
$c
[1] "matrix"
$d
[1] "function"

Given that the last element is the search function, I can call it like so:

> complicated.list[["d"]]()
[1] ".GlobalEnv" ...

As a final comment on this: it should be noted that a data.frame is really a list (from the data.frame documentation):

A data frame is a list of variables of the same number of rows with unique row names, given class ‘"data.frame"’

That's why columns in a data.frame can have different data types, while columns in a matrix cannot. As an example, here I try to create a matrix with numbers and characters:

> a <- 1:4
> class(a)
[1] "integer"
> b <- c("a","b","c","d")
> d <- cbind(a, b)
> d
a b
[1,] "1" "a"
[2,] "2" "b"
[3,] "3" "c"
[4,] "4" "d"
> class(d[,1])
[1] "character"

Note how I cannot change the data type in the first column to numeric because the second column has characters:

> d[,1] <- as.numeric(d[,1])
> class(d[,1])
[1] "character"


Related Topics



Leave a reply



Submit