# Vertical alignment in longtable headers

I have a problem in which the header cells of my longtable are not properly aligned. The text in the first header appears to be bottom-aligned (or perhaps have a mystery newline before it) while the text in the second and third cells appears to be top-aligned (or has a mystery line after it.)

\documentclass{report}

\usepackage{longtable}

% Define an easy way to make line breaks within tables
\newcommand{\specialcell}[2][t]{
\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}

%===----- Functions for indexing and typesetting -----=====
\newcommand{\fun}[1]{\texttt{#1}\index{#1}}
\newcommand{\FUN}[1]{\texttt{#1}\index{#1|textbf}}
\newcommand{\code}[1]{\texttt{#1}}

\begin{document}
\SweaveOpts{concordance=TRUE}

\begin{longtable}{p{0.12\textwidth} | p{0.50\textwidth} | p{0.38\textwidth}}
\label{tab:basicfunctions}

\textbf{Function} & \textbf{What it does} & \textbf{Example use} \\ \hline

\fun{:} & A handy little function that generates a sequence of numbers, counting by 1, backwards or forwards. & \specialcell{\code{0:18} \\ \code{48:-8}} \\
\fun{?} & Finds help files for a specific function, package or dataset. & \code{?max}\\
\fun{??} & Finds help files that match a given topic & \code{??correlation}\\
\fun{c} & Combines input to form a vector. Input must be of the same data type (e.g., only letters, only numbers, etc.) & \specialcell{\code{c(1,2,5,9)}\\ \code{c("imagine","that")}} \\
\fun{cor} & Returns the correlation between two vectors, or between the columns of a matrix. & \code{cor(c(1,3,5,7),c(4,2,8,6))}\\
\fun{cumsum} & Calculates the cumulative sum of its input. For vectors, it returns a vector. For matrices, it adds down a column first, then continues with the next column. The result is returned as a vector. & \code{cumsum(c(5,10,2,9))}\\
\fun{diff} & Calculates the sequential difference between a series of numbers. & \code{diff(c(2,4,5,8))}\\
\fun{dir} & Lists the files in a directory or folder. Default is the current directory, but other locations can be provided. The same as \fun{list.files}. & \specialcell{\code{dir()}\\\code{dir("C:/")} (Windows) \\ \code{dir("/Users/")} (Mac)} \\
\fun{example} & Runs the example code at the bottom of the help page for a given function. & \code{example(cumsum)} \\
\fun{head} & Shows the first six elements of a vector or the first six rows of a matrix. & \code{head(letters)} \\
\FUN{intersect} & Returns the matching elements of two vectors. & \code{intersect(c(2,4),c(1,2))} \\
\fun{length} & Returns the length of a vector. For a matrix, it returns the total number of elements. & \code{length(LETTERS)} \\
\fun{list.files} & The same as \code{dir}; provides a list of files in a directory. & \specialcell{\code{list.files()}\\ \code{list.files("C:/")} (Windows) \\ \code{list.files("/Users/")} (Mac)} \\
\fun{ls} & Gives the names of all the objects currently in working memory. & \code{ls()}\\
\fun{max} & Returns the largest value in its input. & \code{max(1:100)} \\
\fun{mean} & Returns the arithmetic average of its input. & \code{mean(c(1,2,3,10))} \\
\fun{median} & Returns the middle value of its input. & \code{median(c(1,2,3,10)} \\
\fun{min} & Returns the smallest value in its input. & \code{min(1:100)}\\
\fun{nchar} & Gives the number of characters in each element of a vector containing strings of text. & \code{nchar(c("imagine","that"))}\\
\fun{order} & Returns the order of elements in a vector. Note that this does not sort the vector. Instead, it tells you how the elements of the vector would need to be rearranged to sort them. & \code{order(c(9,5,8,2))} \\
\fun{rep} & Repeats its input a given number of times. Can be used on numbers, characters, and other kinds of data. & \specialcell{\code{rep(1,5)} \\ \code{rep(1:3,5)} \\ \code{rep("okay",10)}} \\
\fun{rev} & Reverses the contents of its input, and returns them as a vector. & \code{rev(c("is","it","cool"))} \\
\end{longtable}

\end{document}


The results look like this:

PS. If you happen to know why my \specialcells{} appear indented in the typeset output, I'd love to know that, too...

I do not know what \SweaveOpts is so I have just commented it out.

Your two problems are caused by extra space: the blank line before \textbf{Function} and the "empty" space in

\newcommand{\specialcell}[2][t]{
\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}


It is better to either put the full macro definition on one line, as below, or to put a % at the end of internal lines when writing macros. Depending on the macro it may not introduce extra space if you don't do this but, as in your example, it often does.

If you get rid of both of these them your problems disappear and your output looks like:

Here is the full code:

\documentclass{report}

\usepackage{longtable}

% Define an easy way to make line breaks within tables
\newcommand{\specialcell}[2][t]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}

%===----- Functions for indexing and typesetting -----=====
\newcommand{\fun}[1]{\texttt{#1}\index{#1}}
\newcommand{\FUN}[1]{\texttt{#1}\index{#1|textbf}}
\newcommand{\code}[1]{\texttt{#1}}

\begin{document}
%\SweaveOpts{concordance=TRUE}

\begin{longtable}{p{0.12\textwidth} | p{0.5\textwidth} | p{0.38\textwidth}}
\label{tab:basicfunctions}%
\textbf{Function} & \textbf{What it does} & \textbf{Example use} \\ \hline
%
\fun{:} & A handy little function that generates a sequence of numbers, counting by 1, backwards or forwards. & \specialcell{\code{0:18} \\ \code{48:-8}} \\
\fun{?} & Finds help files for a specific function, package or dataset. & \code{?max}\\
\fun{??} & Finds help files that match a given topic & \code{??correlation}\\
\fun{c} & Combines input to form a vector. Input must be of the same data type (e.g., only letters, only numbers, etc.) & \specialcell{\code{c(1,2,5,9)}\\ \code{c("imagine","that")}} \\
\fun{cor} & Returns the correlation between two vectors, or between the columns of a matrix. & \code{cor(c(1,3,5,7),c(4,2,8,6))}\\
\fun{cumsum} & Calculates the cumulative sum of its input. For vectors, it returns a vector. For matrices, it adds down a column first, then continues with the next column. The result is returned as a vector. & \code{cumsum(c(5,10,2,9))}\\
\fun{diff} & Calculates the sequential difference between a series of numbers. & \code{diff(c(2,4,5,8))}\\
\fun{dir} & Lists the files in a directory or folder. Default is the current directory, but other locations can be provided. The same as \fun{list.files}. & \specialcell{\code{dir()}\\\code{dir("C:/")} (Windows) \\ \code{dir("/Users/")} (Mac)} \\
\fun{example} & Runs the example code at the bottom of the help page for a given function. & \code{example(cumsum)} \\
\fun{head} & Shows the first six elements of a vector or the first six rows of a matrix. & \code{head(letters)} \\
\FUN{intersect} & Returns the matching elements of two vectors. & \code{intersect(c(2,4),c(1,2))} \\
\fun{length} & Returns the length of a vector. For a matrix, it returns the total number of elements. & \code{length(LETTERS)} \\
\fun{list.files} & The same as \code{dir}; provides a list of files in a directory. & \specialcell{\code{list.files()}\\ \code{list.files("C:/")} (Windows) \\ \code{list.files("/Users/")} (Mac)} \\
\fun{ls} & Gives the names of all the objects currently in working memory. & \code{ls()}\\
\fun{max} & Returns the largest value in its input. & \code{max(1:100)} \\
\fun{mean} & Returns the arithmetic average of its input. & \code{mean(c(1,2,3,10))} \\
\fun{median} & Returns the middle value of its input. & \code{median(c(1,2,3,10)} \\
\fun{min} & Returns the smallest value in its input. & \code{min(1:100)}\\
\fun{nchar} & Gives the number of characters in each element of a vector containing strings of text. & \code{nchar(c("imagine","that"))}\\
\fun{order} & Returns the order of elements in a vector. Note that this does not sort the vector. Instead, it tells you how the elements of the vector would need to be rearranged to sort them. & \code{order(c(9,5,8,2))} \\
\fun{rep} & Repeats its input a given number of times. Can be used on numbers, characters, and other kinds of data. & \specialcell{\code{rep(1,5)} \\ \code{rep(1:3,5)} \\ \code{rep("okay",10)}} \\
\fun{rev} & Reverses the contents of its input, and returns them as a vector. & \code{rev(c("is","it","cool"))} \\
\end{longtable}

\end{document}

• @alwaysask Yes, you're right. Thank you. Fixed! – Andrew Aug 9 '16 at 13:37
• Thanks very much! This explains two things that bedeviled me for hours. Your explanation is very clear and gets right to heart of both my questions. – Sasc Aug 9 '16 at 23:48
• Ah, and as a side note: I am using RStudio as a markdown environment. It adds the \SweaveOpts line. (Even when repeatedly deleted.) This was only occurring in my minimal example -- the larger document has other settings to avoid this. – Sasc Aug 9 '16 at 23:57

Your table produces some margin overflows. Also, I think you shouldn't reinvent the wheel: there's already a package (makecell) which allows for line breaks in cells. So I propose to use the ltablex package, which brings the functionalities of longtable to tabularx. Using a tabularx environment will avoid overflowing into the margin. Additionally, I removed the vertical lines in favour of the rules of booktabs, which have some vertical padding around them, and loaded the cellspace package, which defines minimal vertical spacing above and below cells, so that the different rows are clearly distinct. Finally, I simplified your code: you don't really need to use \code in your last column:

\documentclass{report}
\usepackage{geometry} \usepackage{booktabs, ltablex}
\usepackage{makecell} % Define an easy way to make line breaks within tables
\renewcommand\cellalign{lt}
\usepackage{cellspace}
\setlength\cellspacetoplimit{6pt}
\setlength\cellspacebottomlimit{6pt}
%===----- Functions for indexing and typesetting -----=====
\newcommand{\fun}[1]{\texttt{#1}\index{#1}}
\newcommand{\FUN}[1]{\texttt{#1}\index{#1|textbf}}
\newcommand{\code}[1]{\texttt{#1}}

\begin{document}
%\SweaveOpts{concordance=TRUE}

\keepXColumns
\begin{tabularx}{\linewidth}{SlX >{\ttfamily}Sl}
\label{tab:basicfunctions}
%\toprule
\midrule
\endfoot
\bottomrule
\endlastfoot
%
\fun{:} & A handy little function that generates a sequence of numbers, counting by 1, backwards or forwards. & \makecell{0:18 \\ 48:-8} \\
\fun{?} & Finds help files for a specific function, package or dataset. & ?max \\
\fun{??} & Finds help files that match a given topic & ??correlation \\
\fun{c} & Combines input to form a vector. Input must be of the same data type (e.g., only letters, only numbers, etc.) & \makecell{c(1,2,5,9)\\ c("imagine","that")} \\
\fun{cor} & Returns the correlation between two vectors, or between the columns of a matrix. & cor(c(1,3,5,7),c(4,2,8,6))\\
\fun{cumsum} & Calculates the cumulative sum of its input. For vectors, it returns a vector. For matrices, it adds down a column first, then continues with the next column. The result is returned as a vector. & cumsum(c(5,10,2,9)) \\
\fun{diff} & Calculates the sequential difference between a series of numbers. & diff(c(2,4,5,8)) \\
\fun{dir} & Lists the files in a directory or folder. Default is the current directory, but other locations can be provided. The same as \fun{list.files}. & \makecell{dir()\\dir("C:/") (Windows) \\ dir("/Users/") (Mac)} \\
\fun{example} & Runs the example code at the bottom of the help page for a given function. & example(cumsum) \\
\fun{head} & Shows the first six elements of a vector or the first six rows of a matrix. & head(letters) \\
\FUN{intersect} & Returns the matching elements of two vectors. & intersect(c(2,4),c(1,2)) \\
\fun{length} & Returns the length of a vector. For a matrix, it returns the total number of elements. & length(LETTERS) \\
\fun{list.files} & The same as \code{dir}; provides a list of files in a directory. & \makecell{list.files()\\ list.files("C:/") (Windows) \\ list.files("/Users/") (Mac)} \\
\fun{ls} & Gives the names of all the objects currently in working memory. & ls()\\
\fun{max} & Returns the largest value in its input. & max(1:100) \\
\fun{mean} & Returns the arithmetic average of its input. & mean(c(1,2,3,10)) \\
\fun{median} & Returns the middle value of its input. & median(c(1,2,3,10) \\
\fun{min} & Returns the smallest value in its input. & min(1:100) \\
\fun{nchar} & Gives the number of characters in each element of a vector containing strings of text. & nchar(c("imagine","that")) \\
\fun{order} & Returns the order of elements in a vector. Note that this does not sort the vector. Instead, it tells you how the elements of the vector would need to be rearranged to sort them. & order(c(9,5,8,2)) \\
\fun{rep} & Repeats its input a given number of times. Can be used on numbers, characters, and other kinds of data. & \makecell{rep(1,5) \\ rep(1:3,5) \\ rep("okay",10)} \\
\fun{rev} & Reverses the contents of its input, and returns them as a vector. & rev(c("is","it","cool")) \\
\end{tabularx}

\end{document}


• Thanks very much for your answer. Your suggestions are probably more aesthetically pleasing than my original example, but unfortunately we are somewhat constrained by existing styles in the rest of the project. However, these packages offer a great alternative and I definitely learned something new. – Sasc Aug 9 '16 at 23:49
• booktabs ios not mandatory here. It was just to give an example of what can be done. So you can restore the vertical lines and the usual \hlines. More importantly, this table does not overflow into the margin, due to the use of a X column and tabularx. – Bernard Aug 9 '16 at 23:57