Let's suppose I have a list:
[[1]]
[1] 0.7125856 -1.4871811 0.6230076 1.0756424 0.8172592 -0.1327926 -0.7674947 -1.0738684 1.5706677
[10] -0.6674960
[[2]]
[1] -0.5778682 -1.1186447 0.8272505 0.5123162 0.6607654 1.6559877 -0.7961859 -0.8966686
[[3]]
[1] -1.42867999 -0.21142100 -2.89762370 0.11036288 0.66846399 -0.77309213 0.35278541 -0.99579117 -0.73043142
[10] -0.01857864 -0.93654969 0.46751328
[[4]]
[1] -0.483896685 -0.207550362 -0.902920637 -0.008191134 -1.015636093
And I also have a vector with indices of so-called "central" values of vectors in this list:
[1] 2 4 5 1
What I'm trying to get is for given range (for example, 3) get subsets of vectors around those centers with the length of range in both sides. So every subset must be length of 7 and if range extends beyond length of vector there must be NAs added:
[[1]]
[1] NA NA 0.7125856 [-1.4871811] 0.6230076 1.0756424 0.8172592
[[2]]
[1] -0.5778682 -1.1186447 0.8272505 [0.5123162] 0.6607654 1.6559877 -0.7961859
[[3]]
[1] -0.2114210 -2.8976237 0.1103629 [0.6684640] -0.7730921 0.3527854 -0.9957912
[[4]]
[1] NA NA NA [-0.483896685] -0.207550362 -0.902920637 -0.008191134
I put centers in brackets, because SO doesn't allow bold text in a code. Is there a way to do something like this in R?
I think you're looking for something like this?
Data:
n <- 10
x <- list(rnorm(n),rnorm(n),rnorm(n),rnorm(n))
i <- c(2,4,5,1)
r <- 3
Possible solution:
f <- function(x) ifelse((x-r):(x+r) %in% 1:n,(x-r):(x+r),NA)
tmp <- lapply(i,f)
out <- mapply("[",x,tmp)
split(out,col(out))
$`1`
[1] NA NA 0.8120232 0.4980624 -2.9708413 0.6754918 -0.9900322
$`2`
[1] -1.0303741 -1.7432638 0.9466315 -1.3322712 -1.7281613 -0.1951453 0.3789493
$`3`
[1] -1.4120119 0.3675425 -0.8378275 -1.1080856 -0.9369994 1.0823376 1.2194782
$`4`
[1] NA NA NA 0.1757164 -1.5768032 0.3121876 0.4443616
Related
I want to loop through a list of string to another list
cutter_Ch <- c('happy','birthday','Lucia')
pos <- c('Lucia','today')
one way I can do it is with lapply
pos.matches = lapply(cutter_Ch, pmatch, pos)
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] 1
However, I want the function return the matched string instead of NA and number of times matched, like this
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] Lucia
We need to use the index to subset the 'pos'
lapply(cutter_Ch, function(x) pos[pmatch(x, pos)])
It is not clear whether this example is simplified version of something more complex. Anyway, with str_extract we can get the same output in a vector
library(stringr)
str_extract(cutter_Ch, paste(pos, collapse="|"))
#[1] NA NA "Lucia"
a is a list. a<-list(1,3,4,2,5,6)
b is also a list. b<-list(c(1,2),4,5,6,7,8)
p is an indicator. p<-c(T,F,T,T,T,T)
If p is true, then we replace a with b at the respective position. Otherwise, just keep a as it was.
So the expected result is as follows:
[[1]]
[1] 1 2
[[2]]
[1] 3
[[3]]
[1] 5
[[4]]
[1] 6
[[5]]
[1] 7
[[6]]
[1] 8
I used the following code to calculate:
replace(a,b,p)
However, it turned out that:
Error in replace(a, b, p) : invalid subscript type 'list'
Could you help with this, thank you!
I think this should work:
a[p]<-b[p]
or:
ifelse(p, b, a)
Say I have the following:
seq<-c(2,3,4)
added<-lapply(1:length(seq),function(i){
seq[i]+1
}
)
> added
[[1]]
[1] 3
[[2]]
[1] 4
[[3]]
[1] 5
How do I use the list elements in seq to name the list elements of 'added'?
i.e.
> added
[[2]]
[1] 3
[[3]]
[1] 4
[[4]]
[1] 5
thank you
ACCEPTED SOLUTION from #akrun
seq<-c(2,3,4)
added<-setNames(lapply(1:length(seq),function(i){
seq[i]+1
}
),seq1)
You could try
added <- setNames(added, seq)
Or
names(added) <- seq
library(purrr)
seq<-c(2,3,4)
set_names(seq, seq_along(seq))
or
seq %>%
set_names(seq_along(.))
Can someone explain what's happening in this example code? I have a function which does a calculation loop and as always, wanted to initialize my output vector instead of incrementing it each time thru the loop.
Rgames> library(Rmpfr)
Rgames> foo<-rep(NA,5)
Rgames> foo
[1] NA NA NA NA NA
Rgames> rfoo<-mpfr(rep(NA,5),20)
Rgames> rfoo
5 'mpfr' numbers of precision 20 bits
[1] NaN NaN NaN NaN NaN
Rgames> for(jj in 1:5) {
+ foo[jj]<- mpfr(jj,10)
+ rfoo[jj]<-mpfr(jj,10)
+ }
Rgames> rfoo
5 'mpfr' numbers of precision 10 bits
[1] 1 2 3 4 5
Rgames> foo
[[1]]
'mpfr1' 1
[[2]]
'mpfr1' 2
[[3]]
'mpfr1' 3
[[4]]
'mpfr1' 4
[[5]]
'mpfr1' 5
I don't understand why, apparently, the existing non-mpfr vector foo is not only coerced to a list, but then each time through the loop, the new value is inserted into foo[jj] as a list, giving me an unpleasant "list of lists" . The mpfr vector rfoo does what I expected I'd get in both cases. (I checked, and if I do not initialize, and put something inside the loop like foo<-c(foo,mpfr(jj,10)) I do get a result equivalent to rfoo)
What's happening here is the same thing that would happen if you were working with lists instead of mpfr objects. For example, as follows. I believe this makes sense because S4 objects are stored in a similar way to lists, but I'm not an S4 expert.
> foo <- rep(NA,2)
> foo
[1] NA NA
> foo[1] <- list(1)
> foo
[[1]]
[1] 1
[[2]]
[1] NA
I believe that what happens is that the original atomic vector gets coerced to a list to be able to include the object that you've asked to put there. I can't find any documentation about that right here; I think it's discussed in Chambers's book but don't have that at hand.
One can easily recreate this behavior using S3 methods as well; first the S3 methods to create a new class:
mynum <- function(x) {structure(as.list(x), class="mynum")}
print.mynum <- function(x) { cat("My numbers are:\n")
print(do.call(paste, x), quote=FALSE) }
Here's what happens if you start with an atomic vector:
> (foo <- rep(NA, 2))
[1] NA NA
> foo[1] <- mynum(1)
> foo
[[1]]
[1] 1
[[2]]
[1] NA
and here's what happens if you start with the mynum vector:
> (rfoo <- mynum(rep(NA, 2)))
My numbers are:
[1] NA NA
> rfoo[1] <- mynum(1)
> rfoo
My numbers are:
[1] 1 NA
I use apply to a matrix in order to apply a function row by row.
My syntax is as follows :
res = apply(X,1,MyFunc)
The above function MyFunc returns a list of two values.
But the result of this apply application is a strange structure, where R seems to add some of its own (housekeeping?) data :
res = $`81`
$`81`$a
[1] 80.8078
$`81`$b
[1] 6247
Whereas the result I am waiting for is simply :
res = $a
[1] 80.8078
$b
[1] 6247
I do not know why this strange 81 is inserted by R and how can I get rid of it.
Thanks for help
This is perfectly normal behaviour. You are applying a function over a matrix with named rows. Your function returns a list for each row, and each element in this new list of lists is named with the corresponding rowname.
Here is an example that reproduces what you describe:
x <- matrix(1:4, nrow=2)
rownames(x) <- 80:81
myFunc <- function(x)list(a=1, b=2)
xx <- apply(x, 1, myFunc)
xx
This returns:
$`80`
$`80`$a
[1] 1
$`80`$b
[1] 2
$`81`
$`81`$a
[1] 1
$`81`$b
[1] 2
Take a look at the structure of this list:
str(xx)
List of 2
$ 80:List of 2
..$ a: num 1
..$ b: num 2
$ 81:List of 2
..$ a: num 1
..$ b: num 2
To index the first element, simply use xx[[1]]:
xx[[1]]
$a
[1] 1
$b
[1] 2
Here is a guess as to what you may have intended... Rather than returning a list, if you return a vector, the result of the apply will be a matrix:
myFunc <- function(x)c(a=1, b=2)
apply(x, 1, myFunc)
80 81
a 1 1
b 2 2
And to get a specific row, without names, do:
unname(xx[2, ])
[1] 2 2
It would help to know what your matrix (X) looks like. Let's try something like this:
mf <- function(x) list(a=sum(x),b=prod(x))
mat <- matrix(1:6,nrow=2)
Then:
> apply(mat,1,mf)
[[1]]
[[1]]$a
[1] 9
[[1]]$b
[1] 15
[[2]]
[[2]]$a
[1] 12
[[2]]$b
[1] 48
You need that first subscript to differentiate between the lists that each row will generate. I suspect that your rownames are numbered, which results in the $`81` that you are seeing.