通过与列名称中的模式匹配的data.frame的不同列迭代函数

时间:2013-08-15 12:47:00

标签: r for-loop lapply

我想通过data.frame的不同列(在列名中使用通用模式)迭代函数。 对于data.frame的子集,我使用这个有效的代码:

df[,grep("abc", colnames(df))]

但我不知道如何将我的函数f(x)应用于匹配此模式的所有列,使用for循环或lapply函数。

我正在使用的功能是:

compress= function(x) {
  aggregate(df[,x,drop=FALSE],
        list(hour = with(df,paste(dates(Time),
                                         sprintf("%d:00:00",hours(Time))))),
        sum,na.rm=TRUE)
}

其中df(数据框)和Time可以设置为变量本身,但目前我不需要这样做。

由于 朱

1 个答案:

答案 0 :(得分:6)

你基本上得到了它。只需在子集数据的列上使用apply通过列apply函数f2的第二个参数中的apply表示列,而不是至1表示行apply的行:)

apply( df[,grep("abc", colnames(df))] , 2 , f )

或者,如果您不想将df强制转换为matrixapply会发生这种情况),您可以按照您的建议使用lapply同样的方式......

lapply( df[,grep("abc", colnames(df))] , f )

lapply的返回值将是一个列表,每列有一个元素。您可以通过将data.frame电话与lapply一起打包,将其重新转换为data.frame,例如data.frame( lapply(...) )

实施例

# This function just multiplies its argument by 2
f <- function(x) x * 2

df <- data.frame( AB = runif(5) , AC = runif(5) , BB = runif(5) )


apply( df[,grep("A", colnames(df))] , 2 , f )
#            AB        AC
#[1,] 0.4130628 1.3302304
#[2,] 0.2550633 0.1896813
#[3,] 1.5066157 0.7679393
#[4,] 1.7900907 0.5487673
#[5,] 0.7489256 1.6292801


data.frame( lapply( df[,grep("A", colnames(df))] , f ) )
#         AB        AC
#1 0.4130628 1.3302304
#2 0.2550633 0.1896813
#3 1.5066157 0.7679393
#4 1.7900907 0.5487673
#5 0.7489256 1.6292801

# Note the important difference between the two methods...
class( data.frame( lapply( df[,grep("A", colnames(df))] , f ) ) )
#[1] "data.frame"
class( apply( df[,grep("A", colnames(df))] , 2 , f ) )
#[1] "matrix"

第二次编辑

对于要运行的示例函数,可能更容易将其重写为以df作为输入和要操作的列名向量的函数。在此示例中,函数返回一个列表,该列表的每个元素都包含一个聚合的data.frame

compress= function( df , x ) {
  lapply( x , function(x){
  aggregate(df[,x,drop=FALSE],
        list(hour = with(df,paste(dates(Time),
                                         sprintf("%d:00:00",hours(Time))))),
        sum,na.rm=TRUE)
    }
  )
}

要运行该函数,您只需调用它,向其传递data.frame和一个colnames向量...

compress( df , names(df)[ grep("abc", names(df) ) ] )