循环保持变量名R

时间:2018-07-30 16:18:20

标签: r loops

我想在3个数据帧上创建一个循环,并为每个数据帧创建一个子集,并为这些新的子集分配一个新名称。如何在保持名称的同时循环这三个数据帧?

例如,我有3个数据框:苹果,浆果和葡萄。进行循环时,是否有办法为新的子集数据帧分配与其各自原始数据帧相似的名称?

写出来没有循环,这就是代码的样子。

apples <- data.frame(type = c("red", "golden", "green"), number = c(1, 2, 3))
berries <- data.frame(type = c("blueberry", "raspberry", "mulberry"), number = c(1, 2, 3))
grapes <- data.frame(type = c("red", "green", "sour"), number = c(1, 2, 3))

apples_large <- subset(apples, number > 2)
apples_small <- subset(apples, number < 2)

berries_large <- subset(berries, number > 2)
berries_small <- subset(berries, number < 2)

grapes_large <- subset(grapes, number > 2)
grapes_small <- subset(grapes, number < 2) 

3 个答案:

答案 0 :(得分:4)

通过“数字”列将数据集对象放在listsplit中,以获取嵌套的list数据集

lapply(list(apples, berries, grapes), function(x) split(x, x$number>2)) 

如果我们创建一个命名为list的文件,那么识别或提取各个组件会变得更加容易

out <- lapply(mget(c("apples", "berries", "grapes")),
  function(x) split(x, c("small", "large")[(x$number > 2) + 1]))
out$apples$small

正如@JonMinton所提到的,如果我们需要删除具有'number'2的行

lapply(mget(c("apples", "berries", "grapes")),
       function(x) {x1 <- subset(x, number != 2)
             split(x1, c("small", "large")[(x1$number > 2) + 1])})   

答案 1 :(得分:3)

在全局环境中创建许多对象而不是将它们保存在列表中是一个坏主意,但这可以做到:

tmp <- c("apples", "berries", "grapes")

for (i in 1:length(tmp)){
  assign(paste0("big_", tmp[i]), subset(get(tmp[i]), number > 2))
  assign(paste0("small_", tmp[i]), subset(get(tmp[i]), number < 2))
}

(或使用seq_along(tmp)代替1:length(tmp)

请注意,将assign用于输出,将get用于输入。

答案 2 :(得分:1)

首先,将data.frames放入list中,然后定义一个对行进行分类的函数。现在,您可以根据split中的分类器来lapply列表中的每个元素。

fruits <- list(
    apples=data.frame(type = c("red", "golden", "green"), number = c(1, 2, 3)),
    berries=data.frame(type = c("blueberry", "raspberry", "mulberry"), number = c(1, 2, 3)),
    grapes=data.frame(type = c("red", "green", "sour"), number = c(1, 2, 3))
)

clsfy <- function(num) {
    if (num>2) {
        ret <- "Large"
    } else if (num<2) {
        ret <- "Small"
    } else {
        ret <- NA ## if no condition is met, discard this row
    }
    return(ret)
}

fruits2 <- lapply(fruits, function(fr) {
    split(fr, sapply(fr$number, clsfy))
})

此时,fruits2看起来像这样:

>     fruits2
$apples
$apples$Large
   type number
3 green      3

$apples$Small
  type number
1  red      1


$berries
$berries$Large
      type number
3 mulberry      3

$berries$Small
       type number
1 blueberry      1


$grapes
$grapes$Large
  type number
3 sour      3

$grapes$Small
  type number
1  red      1

要使用每行不止一列来归纳分类,可以使用apply代替sapply,然后重新定义clsfy函数,使其占据整行:{{ 1}}。另一方面,如果您的条件确实是简单的二进制文件,那么split(fr, apply(fr, 1, clsfy))ifelse好。