仅在某些变量/嵌套循环中使用lapply中的sapply

时间:2018-05-21 17:48:01

标签: r nested-loops lapply sapply

我想分两步解决我的问题,以便让我更好地理解编码方式。

第1部分:

假设我有一个这样的列表:

x <- data.frame(replicate(5,sample(0:100,10,rep=TRUE)))

y <- data.frame(replicate(5,sample(0:100,10,rep=TRUE)))

z <- list(x, y)

我想获得每个列表中每列的数字范围。 我真的不明白如何将lapply与sapply结合起来获取列表中每列数据帧的结果。关于我如何做到这一点的任何想法?

如果我想让第一个列表元素的第三列说出来,那么我能够正常运行的是:

range(z[[1]][[2]])

第2部分:

我的问题的第二部分更进一步。这次我将添加一个包含字符的列到我的数据帧。

a <- data.frame(replicate(5,sample(0:100,10,rep=TRUE)))
a$x6 <- letters[1:10]

b <- data.frame(replicate(5,sample(0:100,10,rep=TRUE)))
b$x6 <- letters[1:10] 

c <- list(x, y)

我想得到每个列表中每列的数字范围,但第6列不是数字。我不想删除此列,而只想查询数字列。

关于如何有效地做到这一点的任何想法?我认为lapply和sapply的组合将是最好的。

如果您对如何使用嵌套循环有所了解,那么知道这一点也很有趣。也许第二部分也只适用于嵌套循环......

2 个答案:

答案 0 :(得分:3)

第一个可以用

完成
lapply(z, function(a) sapply(a,range))

[[1]]
     X1 X2 X3 X4 X5
[1,]  2 13 28  2  3
[2,] 95 97 98 99 85

[[2]]
     X1 X2 X3 X4  X5
[1,]  7  4 16  5  19
[2,] 90 90 82 84 100

第二个可以用

完成
lapply(c, function(a) sapply(a[sapply(a,is.numeric)],range))

[[1]]
     X1 X2 X3 X4 X5
[1,]  7  5  0  3  8
[2,] 97 81 96 93 94

[[2]]
     X1 X2  X3 X4 X5
[1,]  8  4   0  9  7
[2,] 72 90 100 99 94

这个中的内部sapply创建了c的每个元素的列索引的逻辑向量,它们是数字的,所以它会使字符列不在循环中。

顺便说一句,在R中使用c作为变量名是一个坏主意,因为它也是一个常见的函数!

答案 1 :(得分:0)

第一个使用嵌套函数很简单。

lapply(z, function(d) { sapply(d, range) })
[[1]]
     X1 X2 X3 X4  X5
[1,]  7  0  1  0   1
[2,] 86 82 96 91 100

[[2]]
     X1 X2 X3 X4 X5
[1,]  6  0  3 14  1
[2,] 98 84 99 89 73

对于第二个,嵌套函数开始变得有点丑陋:

> lapply(z, function(d) {
   sapply(d, function(col) {
    if (is.numeric(col)) { range(col) } else { c(NA, NA) }
   })
  })
[[1]]
     X1 X2 X3 X4 X5 x6
[1,]  8  0  3 12  0 NA
[2,] 93 97 92 97 97 NA

[[2]]
     X1  X2 X3 X4 X5 x6
[1,] 20  31 10  5 17 NA
[2,] 84 100 88 94 99 NA