'what's going on? 
The offender here is table. 


LL <- as.list(DT[, list(x1, x2)])
lapplyTable <- lapply(LL, table)

is(lapplyTable[[1]])

# none of these are what we want
do.call(rbind, lapplyTable)
do.call(cbind, lapplyTable)
c(lapplyTable)
unlist(lapplyTable)

DT[, {Z <- sapply(.SD, function(x) unlist(table(x))); dput(Z); Z}, by=y]



http://stackoverflow.com/questions/15862564/data-table-create-new-columns-with-lapply

# DATA: 
set.seed(9)
DT <- data.table(x1=letters[sample(x=2L,size=6,replace=TRUE)],
                 x2=letters[sample(x=2L,size=6,replace=TRUE)],
                 y=rep(1:2,3), key="y")

# GOAL:

DT[, lapply(.SD, table), by = y]
# Desired Result, something like this:
# x1_a x2_a x2_b
#    3    2    1
#    3    2    1




--
# SAMPLE DATA, AS FACTOR, with SAME LEVELS
set.seed(9)
levs <- letters[1:2]
DT <- data.table(x1=factor(letters[sample(x=2L,size=6,replace=TRUE)], levels=levs),
                 x2=factor(letters[sample(x=2L,size=6,replace=TRUE)], levels=levs),
                 y=rep(1:2,3), key="y")



===================================================
## 
DT[, as.list(unlist(lapply(.SD, table))), by=y]


If each column in the DT has different levels, then to get a nice output would necessarilly require rehsaping the data.table (or data.frame), 
since by the very nature of the data, you would have varying row sizes if trying to use `lapply(.SD, table)` _(or worse, you would get recycled values, which would incorrectly appear as "counts" of `table`)_


However, if all columns have the same levels, then you can get a nice output using the following:

### THIS WORKS, JUST NEEDS TO BE RESHAPED
> DT[, data.frame(lapply(.SD, table)), by=y]
   y x1.Var1 x1.Freq x2.Var1 x2.Freq
1: 1       a       3       a       2
2: 1       b       0       b       1
3: 2       a       3       a       2
4: 2       b       0       b       1


----

# this gets the column names, where Z is a single output of the lapply statement above
mapply(paste, names(Z), lapply(Z, function(z) as.character(z[["x"]])), MoreArgs=list(sep="_"), SIMPLIFY=FALSE)




DT[, data.frame({X <- c(lev=levels(x1), lapply(.SD, function(x) data.frame(table(x))));
          dput(X);
          X
}), by=y]

Z <- <output of lapply> 
nm <- unlist(<output of mapply>)

# this gets us our frequencies, per value
fr <- unlist(lapply(Z, "[[", "Freq"))

# Thus, the output for a single group of `y` is:
setNames(fr, nm)


----
DT[, data.frame({Z <- lapply(.SD, table); dput(Z);
                 nm <- unlist(mapply(paste, names(Z), lapply(Z, function(z) as.character(z[["x"]])), MoreArgs=list(sep="_"), SIMPLIFY=FALSE))
                fr <- unlist(lapply(Z, "[[", "Freq"))
                print("fr is ----------:")
                dput(fr);
                rbind(setNames(unlist(lapply(Z, "[[", "Freq")), nm))
}), by=y]

## 
DT[, as.list(unlist(lapply(.SD, table))), by=y]



                 nm <- unlist(mapply(paste, names(Z), lapply(Z, function(z) as.character(z[["x"]])), MoreArgs=list(sep="_"), SIMPLIFY=FALSE))
                fr <- unlist(lapply(Z, "[[", "Freq"))
                print("fr is ----------:")
                dput(fr);
                rbind(setNames(unlist(lapply(Z, "[[", "Freq")), nm))
}), by=y]



DT[, data.frame({Z <- lapply(.SD, function(x) data.frame(table(x))));
          dput(X);
          X
}), by=y]


================================================================================================

--------
intermediate brain step: 
--------
DT[, data.frame(cbind(VALUE=unique(c(x1, x2)), do.call(cbind, lapply(.SD, table)))), by=y]

   y VALUE x1 x2
1: 1     1  3  2
2: 1     2  0  1
3: 2     1  3  2
4: 2     2  0  1

--------
DT[, data.frame({X <- c(lev=levels(x1), lapply(.SD, function(x) data.frame(table(x))));
          dput(X);
          X
}), by=y]
--------
DT[, data.frame({X <- c(lev=levels(x1), lapply(.SD, table));
          dput(X);
          X
}), by=y]
--------
