将函数应用于R中每n列的每一行

Applying a function to every row on each n number of columns in R

我的数据包含连续的列 1,2,...,2000。我想为每行 100 列的每组应用 returns 3 个变量的函数。

数据如下所示:

  1       2        3    .....   2000  
0.01    0.0       0.002         0.03
0.005   0.002     0.011         0.04
0.001   0.003     0.004         0.0

这是我试过的代码:

prep_data <- function(df){
  #Create Column names
  colnms<-c()
  for(i in seq(1, 20, 1)){
    
    for(j in seq(1, 3, 1)){
      f<-paste0("grp",i,"_",j)
      colnms=c(colnms,f)
    }
    
  }
  #
  trans <- data.frame(matrix(ncol = 60, nrow = NROW(df)))
  colnames(trans) <-colnms

#Looping over every row
  for (i in 1:NROW(df)){
      X = c()
      #LOOPING over each group of 100 columns
      for(j in seq(1, 1900, 100)){
        end<-j+99
        tmp<-subset(df[i], select=j:end)
        #Here I apply the function over the 100 columns for the current row to get 3 values#
          X = c(X,MY_FUNC(tmp))
         ###################################################################################          
}
      }
#Append the current row
      trans[i,] <- X
  }
  return(trans)
  
}

预期输出(60 列的数据框)如下:

grp1_1  grp1_2    grp1_3 .....  grp20_3  
0.01    0.0       0.002         0.03
0.005   0.002     0.011         0.04
0.001   0.003     0.004         0.0

我的代码运行但速度太慢可能是因为它对所有循环都没有效率

提前致谢

这是一种方法:

d 成为您的 3 行 x 2000 列框架,列名 as.character(1:2000)(请参阅下面的假数据生成)。我们使用 .I 添加行标识符,然后将数据融长,添加 grp 和 column-group 标识符(即标识 20 组 100)。然后按行和组应用你的函数 myfunc(请参阅下文中的 stand-in 函数),并按行和组进行调整。 (我用的是stringr::str_pad在组号前面加0)

# add row identifier
d[, row:=.I]

# melt and add col group identifier
dm = melt(d,id.vars = "row",variable.factor = F)[,variable:=as.numeric(variable)][order(variable,row), grp:=rep(1:20, each=300)]

# get the result (180 rows long), applying myfync to each set of columns, by row
result = dm[, myfunc(value), by=.(row,grp)][,frow:=rep(1:3,times=60)]

# swing wide (3 rows long, 60 columns wide)
dcast(
  result[,v:=paste0("grp",stringr::str_pad(grp,2,pad = "0"),"_",row)],
  frow~v,value.var="V1"
  )[, frow:=NULL][]

输出:(仅前六列)

      grp01_1    grp01_2    grp01_3    grp02_1    grp02_2    grp02_3
        <num>      <num>      <num>      <num>      <num>      <num>
1: 0.54187168 0.47650694 0.48045694 0.51278399 0.51777319 0.46607845
2: 0.06671367 0.08763655 0.08076939 0.07930063 0.09830116 0.07807937
3: 0.25828989 0.29603471 0.28419957 0.28160367 0.31353016 0.27942687

输入:

d = data.table()
alloc.col(d,2000)
set.seed(123)
for(c in 1:2000)  set(d,j=as.character(c), value=runif(3))

myfunc 函数(此答案的玩具示例):

myfunc <- function(x) c(mean(x), var(x), sd(x))