我想在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)
答案 0 :(得分:4)
通过“数字”列将数据集对象放在list
和split
中,以获取嵌套的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
好。