加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

R:快速对数据帧的子集执行操作,然后在没有内部函数的情况下重新

发布时间:2020-12-14 04:59:56 所属栏目:百科 来源:网络整理
导读:我们有一个非常大的数据帧df,可以按因子分割.在由此拆分创建的数据帧的每个子集上,我们需要执行操作以增加该子集的行数,直到它达到一定长度.之后,我们对子集进行调整以获得更大版本的df. 有没有办法在不使用内部函数的情况下快速完成此操作? 假设我们的子集
我们有一个非常大的数据帧df,可以按因子分割.在由此拆分创建的数据帧的每个子集上,我们需要执行操作以增加该子集的行数,直到它达到一定长度.之后,我们对子集进行调整以获得更大版本的df.

有没有办法在不使用内部函数的情况下快速完成此操作?

假设我们的子集操作(在单独的.R文件中)是:

foo< - function(df){magic} 我们想出了几种方法: 1)

df <- split(df,factor)
df <- lapply(df,foo)
rbindlist(df)

2)

assign('list.df',list(),envir=.GlobalEnv) 
assign('i',1,envir=.GlobalEnv)

dplyr::group_by(df,factor)
dplyr::mutate(df,foo.list(df.col))
df <- rbindlist(list.df)
rm('list.df',envir=.GlobalEnv)
rm('i',envir=.GlobalEnv)

(In a separate file)
foo.list <- function(df.cols) {
    magic; 
    list.df[[i]] <<- magic.df
    i <<- i + 1
    return(dummy)
}

第一种方法的问题是时间问题. lapply只需要太长时间才能真正理想(使用我们的数据集大约一个小时).

第二种方法的问题是篡改用户的全球环境的非常不希望的副作用.它明显更快,但如果可以的话,这是我们宁愿避免的.

我们也尝试过传入列表并计算变量,然后尝试用父环境中的变量替换它们(一种黑客来解决R缺乏传递引用).

我们已经研究了一些可能相关的SO问题(R applying a function to a subset of a data frame,Calculations on subsets of a data frame,R: Pass by reference,e.t.c.),但没有一个问题太过清楚.

如果您想运行代码,可以复制和粘贴以下内容:

x <- runif(n=10,min=0,max=3)
 y <- sample(x=10,replace=FALSE)
 factors <- runif(n=10,max=2)
 factors <- floor(factors)
 df <- data.frame(factors,x,y)

df现在看起来像这样(长度10):

Original df

## We group by factor,then run foo on the groups.

 foo <- function(df.subset) {
   min <- min(df.subset$y)
   max <- max(df.subset$y)

   ## We fill out df.subset to have everything between the min and
   ## max values of y. Then we assign the old values of df.subset
   ## to the corresponding spots.

   df.fill <- data.frame(x=rep(0,max-min+1),y=min:max,factors=rep(df.subset$factors[1],max-min+1))
   df.fill$x[which(df.subset$y %in%(min:max))] <- df.subset$x
   df.fill
 }

所以我可以在第一种方法中使用我的示例代码来构建一个新的df(长度为18):

New df

解决方法

使用data.table,由于快速的功能,这不需要很长时间.如果可以,请重写您的函数以使用特定变量.拆分应用组合处理可以提高性能:

library(data.table)
system.time(
df2 <- setDT(df)[,foo(df),factors]
)
#   user  system elapsed 
#   1.63    0.39    2.03

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读