0

Hi I apply a function to each column of a data frame, and for each column it returns a list. Now I wanna convert this list into a matrix or data frame.

Have read this nice post and still have some questions.

df = data.frame(name = c('Tom', 'Mark', 'Jane'),
            weight = c(150, 140, 110),
            sex = c('M', 'M', 'F'), 
            fulltime = c(T, T, F), stringsAsFactors = F)

df$sex = as.factor(df$sex)

# return a list
f1 = function(column){
        list( class = class(column),
              mean = mean(column)
        )
}

lapply + do.call(rbind) works:

result = lapply(df[,], f1)
result

test1 = do.call(rbind.data.frame, result)
test1

# this seems to be same
test2 = as.data.frame(do.call(rbind, result), stringsAsFactors = T) 
test2
identical(test1, test2) # i don't know why not identical...

Why sapply doesn't work - it looks great at first:

result = sapply(df, f1)
result # looks perfect:
#        name        weight    sex      fulltime 
# class "character" "numeric" "factor" "logical"
# mean  NA          133.3333  NA       0.6666667

# but each element is a list
result['class', 'name']
result[1 ,1]
str(result) 

# `unlist` loses row/col names
test = matrix( unlist(result), ncol = ncol(df), byrow = T)
test

# this makes 1D data frame
test1 = do.call(rbind.data.frame, result)
test

Anybody know why a vector can be arranged as 2D like above? Is it the effect of attributes?

And how can we fix the result of sapply(df, f1)? It looks so close to the correct result.

Thanks!

Community
  • 1
  • 1
YJZ
  • 3,934
  • 11
  • 43
  • 67
  • `Reduce(cbind,list)` – MichaelChirico Oct 10 '15 at 14:30
  • 1
    @MichaelChirico I would use `do.call` over `Reduce` as the former is faster. To the OP: You may need an `if` `else` condition to not return the warning for columns that are not numeric. – akrun Oct 10 '15 at 14:31
  • It is better to use `lapply` than `sapply`. but if you really wanted use `simplify=FALSE`, i.e. `str(do.call(rbind.data.frame,sapply(df, f1, simplify=FALSE)))` – akrun Oct 10 '15 at 14:39
  • nice thanks @MichaelChirico! Thanks @akrun yeah I do have `if` `else` in my practical function, min(factor) will even yield error. – YJZ Oct 10 '15 at 14:53

0 Answers0