这是我与R合作的第一周,有一件事我似乎无法管理。
df <- data.frame(a = c(1:10),
b = c("a", "a", "b", "c", "c", "b", "a", "c", "c", "b"))
testF = function(select) {
dum = subset(df, b == select)
}
lapply(unique(df$b), testF)
此功能现在只是在屏幕上打印数据集。但我想将结果存储在我的工作区中作为单独的数据框。在这个例子中,这将给出三个数据帧; a,b和c。
感谢您的帮助。
答案 0 :(得分:2)
Roland针对特定问题提供了正确的解决方案:不需要split()
以上。只是为了确保:split()
返回一个列表。要在工作区中获取单独的数据框,请执行以下操作:
list2env(split(df,df$b),.GlobalEnv)
或者,使用assign:
tmp <- split(df,df$b)
for(i in names(tmp)) assign(i,tmp[[i]])
关于子集的一个词
这就是说,为什么你的功能是完全错误的更详细的。首先,在?subset
中你读到了:
警告强>
这是一种便于交互使用的便利功能。对于 编程最好使用标准的子集函数 [,特别是论证子集的非标准评估 可能会产生意想不到的后果。
转换为:您的生活中永远不会再次使用subset()
函数。
关于从函数返回值的单词
接下来,函数始终返回结果:
return()
语句,则返回return()
作为参数给出的任何内容。在您的情况下,最后一行包含作业。现在,赋值也返回一个值,但是你没有看到它。它返回invisibly
。您可以通过将其包装在括号中来查看它,例如:
> x <- 10
> (x <- 20)
[1] 20
这绝对没必要。这就是为什么你的函数在lapply()
中使用时(lapply捕获不可见输出),但在命令行使用时不会给你任何(可见)输出的原因。你可以抓住它:
> testF("b")
> x <- testF("b")
> x
a b
3 3 b
6 6 b
10 10 b
你的函数中的赋值没有意义:要么显式返回dum
,要么只是完全放弃赋值
纠正您的功能
所以,鉴于这仅仅是一个例子,仅仅使用split()
你的函数将无法解决真正的问题:
testF <- function(select) {
dum <- df[df$b=select,]
return(dum)
}
或简单地说:
testF <- function(select){
df[df$b=select,]
}
答案 1 :(得分:1)
您的功能需要返回值。有关详细信息,请参阅help("function")
。
但是,根据您的具体情况,您只需使用split
:
split(df, df$b)
$a
a b
1 1 a
2 2 a
7 7 a
$b
a b
3 3 b
6 6 b
10 10 b
$c
a b
4 4 c
5 5 c
8 8 c
9 9 c
答案 2 :(得分:1)
使用上述评论中描述的list2env
函数的解决方案,假设您希望使用subset
方法,而不管函数内部是否存在潜在问题。
df <- data.frame(a = c(1:10),
b = c("a", "a", "b", "c", "c", "b", "a", "c", "c", "b"))
testF = function(select) {
dum = subset(df, b == select)
dum # you need to return the data frame resulting from the subset back out of the function
}
my.list = lapply(unique(df$b), testF)
names(my.list) = unique(df$b) # set the names of the list elements to the subsets they represent (a,b,c)
list2env(my.list,envir = .GlobalEnv) # copy the data frames from the list to the Global Environment
如果您有一个简单的示例,就像您描绘的那样,您可以按如下方式逐个访问列表中的元素,并将每个元素分配给变量。
a = my.list[[1]]
b = my.list[[2]]
c = my.list[[3]]
最后,您可以定义内联函数并使用(awesome)data.table
包,从而避免使用子集:
library(data.table)
dt <- data.table(a = c(1:10),
b = c("a", "a", "b", "c", "c", "b", "a", "c", "c", "b"))
my.list = lapply(unique(dt$b), function(select) { dt[b == eval(select)]})
希望这有帮助。