Solution 1. If you want to stick to your initial attempt, you can calculate the corresponding y coordinates for the names of the cars and add them as a separate data source. Use the value inherit.aes = FALSE so that this geom_text layer does not inherit anything from the ggplot object created with ggparcoord() :
library(dplyr) p1 <- ggparcoord(mtcars, columns = c(12, 1, 6), groupColumn = 1) + geom_text(data = mtcars %>% select(carName) %>% mutate(x = 1, y = scale(as.integer(factor(carName)))), aes(x = x, y = y, label = carName), hjust = 1.1, inherit.aes = FALSE) + # optional: remove "carName" from x-axis labels scale_x_discrete(labels = function(x) c("", x[-1])) + # also optional: hide legend, which doesn't really seem relevant here theme(legend.position = "none") p1

Solution 2. This alternative uses carName as a group column and does not pass it as one of the columns of parallel coordinates. (which I think this may be closer to the use cases intended for this function ...) Specifying carName as a group of columns allows the value of the names of the car to be captured in the data slot of the ggplot object created by ggparcoord() this time, so our label geom_text can inherit it directly and even filter only for lines corresponding to variable == "mpg" (or whatever the name of the first column of parallel coordinates is called, in the real case of use). The y coordinates are not distributed as evenly as above, but the geom_text_repel from ggrepel does a great job of offsetting overlapping text labels from each other.
library(dplyr) library(ggrepel) p2 <- ggparcoord(mtcars, columns = c(1, 6), groupColumn = "carName") + geom_text_repel(data = . %>% filter(variable == "mpg"), aes(x = variable, y = value, label = carName), xlim = c(NA, 1)) +

Solution 3/4 : You can actually build the same with ggplot() without relying on extensions that can do unexpected things behind the scenes:
library(dplyr) library(tidyr) library(ggrepel) # similar output to solution 1 p3 <- mtcars %>% select(carName, mpg, wt) %>% mutate(carName.column = as.integer(factor(carName))) %>% gather(variable, value, -carName) %>% group_by(variable) %>% mutate(value = scale(value)) %>% ungroup() %>% ggplot(aes(x = variable, y = value, label = carName, group = carName)) + geom_line() + geom_text(data = . %>% filter(variable == "carName.column"), hjust = 1.1) + scale_x_discrete(labels = function(x) c("", x[-1])) p3 # similar output to solution 2 p4 <- mtcars %>% select(carName, mpg, wt) %>% gather(variable, value, -carName) %>% group_by(variable) %>% mutate(value = scale(value)) %>% ungroup() %>% ggplot(aes(x = variable, y = value, label = carName, group = carName)) + geom_line() + geom_text_repel(data = . %>% filter(variable == "mpg"), xlim = c(NA, 1)) p4

edit
You can also add text labels on the right, for each of the above. Please note that the label space cannot be well spaced, as they are arranged according to wt scalable values:
p1 + geom_text(data = mtcars %>% select(carName, wt) %>% mutate(x = 3, y = scale(wt)), aes(x = x, y = y, label = carName), hjust = -0.1, inherit.aes = FALSE) p2 + geom_text_repel(data = . %>% filter(variable == "wt"), aes(x = variable, y = value, label = carName), xlim = c(2, NA)) p3 + geom_text(data = . %>% filter(variable == "wt"), hjust = -0.1) p4 + geom_text_repel(data = . %>% filter(variable == "wt"), xlim = c(2, NA))
