如何使一个函数适用于数据框而不是列?

时间:2015-03-05 12:05:04

标签: r

我实现了一个小循环,可以完美地为我计算输出

df<- structure(list(V1 = c(0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L)), .Names = "V1", class = "data.frame", row.names = c(NA,-10L))
n<- colSums(df == 1)
N <- nrow(df)
tt <- as.data.frame(seq(1,N, by=1))
xi <-cumsum(df)

for (i in 1:nrow(df)) {
  m<- abs((xi[i,]/n)-(tt[i,]/N))/sqrt((n+N/n*N))
  df$newcolumn[i] <- m
}

现在我想做同样的事情,但对于许多列而不是只有一列 什么变化是n,xi和tt

现在让我们创建一个数据框

df2 <- structure(list(V1 = c(0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L), 
    V2 = c(1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 0L), V3 = c(0L, 
    0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L), V4 = c(0L, 1L, 1L, 0L, 
    1L, 1L, 0L, 0L, 1L, 1L)), .Names = c("V1", "V2", "V3", "V4"
), class = "data.frame", row.names = c(NA, -10L))

我可以计算所有相应的参数,N,n,xi和tt如下

    n<- colSums(df2 == 1)
    N <- nrow(df2)
    tt <- as.data.frame(seq(1,N, by=1))
    xi <-cumsum(df2)

现在我想对只计算一列的循环做同样的事情,我想计算第1列到df2的长度

我试着像下面这样做,但没有奏效 任何想法,更好的方式,所有人都赞赏

newcolumn = matrix (0, nrow(df), ncol(df))
results = matrix (0, nrow(df), ncol(df))
for (i in 1:nrow(df)) {                    
  for (j in 1:length(df)) {               
       m<- abs((xi[i,j]/n[j])-(tt[i,j]/N))/sqrt((n[j]+N/n[j]*N))
       newcolumn[i,j] <- m
       results <- rbind(results, newcolumn[,j]) 
    }
}

1 个答案:

答案 0 :(得分:0)

你可以尝试

  res <-  sapply(df2, function(x) {
            n <- sum(x==1)
            N <- length(x)
            tt <- seq(1, N, by=1)
            xi <- cumsum(x)
           abs((xi/n-tt/N))/sqrt((n+N/n*N))})

或者您可以对某些步骤进行矢量化

n <- colSums(df2==1)
N <- nrow(df2)
tt <- seq(1, N, by=1)
xi <- cumsum(df2)
res1 <- abs(xi/n[col(xi)]-tt/N)/sqrt(n+N/n*N)[col(xi)]
identical(as.data.frame(res), res1)
#[1] TRUE

或使用循环

res2 <-  matrix (0, nrow(df2), ncol(df2))
for(i in 1:nrow(df2)){
for(j in 1:length(df2)){
  res2[i,j] <- abs((xi[i,j]/n[j])-(tt[i,1]/N))/sqrt((n[j]+N/n[j]*N))
 }
}

all.equal(res, res2,check.attributes=FALSE)
#[1] TRUE

,其中

n<- colSums(df2 == 1)
N <- nrow(df2)
tt <- as.data.frame(seq(1,N, by=1))
xi <-cumsum(df2)