从函数返回数据框并将其存储在工作区中

时间:2013-12-20 13:02:10

标签: r return dataframe assign

这是我与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。

感谢您的帮助。

3 个答案:

答案 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)]})

希望这有帮助。