Apply to list of vectors

假如想象 提交于 2019-12-08 07:55:29
## dummy data
set.seed(1)
ll <- as.list(data.frame(matrix(rnorm(10 * 10), ncol = 10)))

R> str(ll)
List of 10
 $ X1 : num [1:10] -0.626 0.184 -0.836 1.595 0.33 ...
 $ X2 : num [1:10] 1.512 0.39 -0.621 -2.215 1.125 ...
 $ X3 : num [1:10] 0.919 0.7821 0.0746 -1.9894 0.6198 ...
 $ X4 : num [1:10] 1.3587 -0.1028 0.3877 -0.0538 -1.3771 ...
 $ X5 : num [1:10] -0.165 -0.253 0.697 0.557 -0.689 ...
 $ X6 : num [1:10] 0.398 -0.612 0.341 -1.129 1.433 ...
 $ X7 : num [1:10] 2.4016 -0.0392 0.6897 0.028 -0.7433 ...
 $ X8 : num [1:10] 0.476 -0.71 0.611 -0.934 -1.254 ...
 $ X9 : num [1:10] -0.569 -0.135 1.178 -1.524 0.594 ...
 $ X10: num [1:10] -0.543 1.208 1.16 0.7 1.587 ...

With this, what you had is correct if you want an atomic vector output. To see the relationship look at the names of the vector elements

R> ( out <- sapply(ll, function(x, K) max(x - K, 0), K = 0.3) )
    X1     X2     X3     X4     X5     X6     X7     X8     X9    X10 
1.2953 1.2118 0.6190 1.0587 0.5811 1.6804 2.1016 0.3107 0.8781 1.2868

they are in the same order as the names of the list elements:

R> names(out)
 [1] "X1"  "X2"  "X3"  "X4"  "X5"  "X6"  "X7"  "X8"  "X9"  "X10"
R> names(ll)
 [1] "X1"  "X2"  "X3"  "X4"  "X5"  "X6"  "X7"  "X8"  "X9"  "X10"
R> all.equal(names(out), names(ll))
[1] TRUE

If you want something back that looks like the original list, then use lapply() instead

R> lapply(ll, function(x, K) max(x - K, 0), K = 0.3)
$X1
[1] 1.295

$X2
[1] 1.212

$X3
[1] 0.619

$X4
[1] 1.059

$X5
[1] 0.5811
....

However, it is not clear that you want the maximum or the parallel maximum, i.e. for each list element a vector retuning x - K or 0, whichever is larger, for each element of x. If you want this, that functionality is in the pmax() function:

R> lapply(ll, function(x, K) pmax(x - K, 0), K = 0.3)
$X1
 [1] 0.00000 0.00000 0.00000 1.29528 0.02951 0.00000 0.18743 0.43832 0.27578
[10] 0.00000

$X2
 [1] 1.21178 0.08984 0.00000 0.00000 0.82493 0.00000 0.00000 0.64384 0.52122
[10] 0.29390

$X3
 [1] 0.6190 0.4821 0.0000 0.0000 0.3198 0.0000 0.0000 0.0000 0.0000 0.1179

$X4
 [1] 1.05868 0.00000 0.08767 0.00000 0.00000 0.00000 0.00000 0.00000 0.80003
[10] 0.46318
....

or via sapply, which simplifies the reuslt to a matrix:

R> sapply(ll, function(x, K) pmax(x - K, 0), K = 0.3)
           X1      X2     X3      X4      X5      X6     X7     X8      X9
 [1,] 0.00000 1.21178 0.6190 1.05868 0.00000 0.09811 2.1016 0.1755 0.00000
 [2,] 0.00000 0.08984 0.4821 0.00000 0.00000 0.00000 0.0000 0.0000 0.00000
 [3,] 0.00000 0.00000 0.0000 0.08767 0.39696 0.04112 0.3897 0.3107 0.87809
 [4,] 1.29528 0.00000 0.0000 0.00000 0.25666 0.00000 0.0000 0.0000 0.00000
 [5,] 0.02951 0.82493 0.3198 0.00000 0.00000 1.13302 0.0000 0.0000 0.29395
 [6,] 0.00000 0.00000 0.0000 0.00000 0.00000 1.68040 0.0000 0.0000 0.03295
 [7,] 0.18743 0.00000 0.0000 0.00000 0.06458 0.00000 0.0000 0.0000 0.76310
 [8,] 0.43832 0.64384 0.0000 0.00000 0.46853 0.00000 1.1656 0.0000 0.00000
 [9,] 0.27578 0.52122 0.0000 0.80003 0.00000 0.26972 0.0000 0.0000 0.07002
[10,] 0.00000 0.29390 0.1179 0.46318 0.58111 0.00000 1.8726 0.0000 0.00000
         X10
 [1,] 0.0000
 [2,] 0.9079
 [3,] 0.8604
 [4,] 0.4002
 [5,] 1.2868
 [6,] 0.2585
 [7,] 0.0000
 [8,] 0.0000
 [9,] 0.0000
[10,] 0.0000

Finally, note that it is good practice to pass into your function all information it needs to run. You are relying on R finding K somewhere. It is much better to have your anonymous function take an argument K and pass along the value of K you wish to use when you call the function. This is what I did above in my examples, e.g.

lapply(ll, function(x, K) pmax(x - K, 0), K = 0.3)
           |___________ FUN ___________| |_ ARGS_|

where the bit I have marked with ARGS is where you supply any further arguments required by the function supplied to argument FUN.

somelist <- list()

somelist[[1]] <- sample(1:100,5)
somelist[[2]] <- sample(1:100,10)
somelist[[3]] <- sample(1:100,15)

k <- 50

somelistmod <- lapply(somelist, function(x) pmax(0,x-k))

Output -

> somelist
[[1]]
[1] 58 27 80 51 57

[[2]]
 [1]  72  81  57  79   2  74 100  49  46  16

[[3]]
 [1]  29  24  37  45  26  25  67  61  63  62  30  69  92  89 100

> somelistmod
[[1]]
[1]  8  0 30  1  7

[[2]]
 [1] 22 31  7 29  0 24 50  0  0  0

[[3]]
 [1]  0  0  0  0  0  0 17 11 13 12  0 19 42 39 50

The main difference is that you need to use lapply instead of sapply, and pmax instead of max to get a pairwise comparison.

shadow

Since you want to return a list, you should use lapply instead of sapply. Furthermore, the function max takes the maximum of your vector x. Use pmaxinstead:

lapply(data,function(x) pmax(x-K,0))

You should replace sapply with lapply if you want to obtain a list:

lapply(data,function(x) max(x-K,0))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!