考虑以下R中的数据帧,
df <- data.frame(ID = 1:7, Group = c(rep(1,2), rep(2, 3), rep(3,2)), Year = c(rep(2011, 4), rep(2012, 3)), X = rnorm(7))
我在base R中工作,并希望以更有效的方式完成以下任务。
Group1 <- df[df$Group == 1,]
Group2 <- df[df$Group == 2,]
Group3 <- df[df$Group == 3,]
在这里,我按组生成了三个独立的数据框架,并为变量命名了一个系统的命名方案。这段代码是重复的,我希望能找到更好的方法(通常我有更多的"组",所以这些丑陋的重复代码行占用了很多空间)。
对于我自己的学习,我也很想看到一个For循环的例子,尽管我确信有更好的方法——类似于:
for (i in 1:3){
Groupi <- df[df$Group == i,] }
虽然这显然是不正确的,但希望你能明白。
我认为您最好使用评论中描述的split
。然而,你可以实现你的循环后使用assign
。
for (i in 1:3) {
assign(paste0("Group", i), df[df$Group==i,])
}
还要注意你的索引,你需要一个逗号来表示"所有列"。
这是@Rupert答案的一个变体,它自动从列中提取级别:
makeGroupVars <- function(baseName,df,column){
levs <- levels(as.factor(column))
for(lev in levs){
assign(paste0(baseName,lev),df[column == lev,],envir = .GlobalEnv)
}
NULL
}
例如,调用makeGroupVars("Group",df, df$Group)
将按预期的方式创建三个变量"Group1", "Group2", "Group3"
。此外,像makeGroupVars("specie_",iris,iris$Species)
这样的调用(其中iris
是一个内置的示例数据框)将能够创建诸如specie_setosa
之类的变量。
做了所有这些,我怀疑简单地使用split
可能是最好的选择。您真的需要一个杂乱的名称空间吗?