R friendly greek characters
I'm not an expert by any means but let's try to analyze the problem. In the end, your R-code needs to be understood by the compiler therefore the source-code of make.names() may be helpful:
names <- as.character(names)names2 <- .Internal(make.names(names, allow_))if (unique) { o <- order(names != names2) names2[o] <- make.unique(names2[o])}names2
Now, .Internal() calls the R-interpreter (written in C) so we need to go a little deeper. The C-code responsible for handling the make.names() request can be found here: https://github.com/wch/r-source/blob/0dccb93e114b00b2fcbe75e8721f11a8f2ffdff4/src/main/character.c
A short snipped:
SEXP attribute_hidden do_makenames(SEXP call, SEXP op, SEXP args, SEXP env){ SEXP arg, ans; R_xlen_t i, n; int l, allow_; char *p, *tmp = NULL, *cbuf; const char *This; Rboolean need_prefix; const void *vmax; checkArity(op ,args); arg = CAR(args); if (!isString(arg)) error(_("non-character names")); n = XLENGTH(arg); allow_ = asLogical(CADR(args)); if (allow_ == NA_LOGICAL) error(_("invalid '%s' value"), "allow_"); PROTECT(ans = allocVector(STRSXP, n)); vmax = vmaxget(); for (i = 0 ; i < n ; i++) { This = translateChar(STRING_ELT(arg, i)); l = (int) strlen(This); /* need to prefix names not beginning with alpha or ., as well as . followed by a number */ need_prefix = FALSE; if (mbcslocale && This[0]) { int nc = l, used; wchar_t wc; mbstate_t mb_st; const char *pp = This; mbs_init(&mb_st); used = (int) Mbrtowc(&wc, pp, MB_CUR_MAX, &mb_st); pp += used; nc -= used; if (wc == L'.') { if (nc > 0) { Mbrtowc(&wc, pp, MB_CUR_MAX, &mb_st); if (iswdigit(wc)) need_prefix = TRUE; } } else if (!iswalpha(wc)) need_prefix = TRUE; } else { if (This[0] == '.') { if (l >= 1 && isdigit(0xff & (int) This[1])) need_prefix = TRUE; } else if (!isalpha(0xff & (int) This[0])) need_prefix = TRUE; } if (need_prefix) { tmp = Calloc(l+2, char); strcpy(tmp, "X"); strcat(tmp, translateChar(STRING_ELT(arg, i))); } else { tmp = Calloc(l+1, char); strcpy(tmp, translateChar(STRING_ELT(arg, i))); } if (mbcslocale) { /* This cannot lengthen the string, so safe to overwrite it. */ int nc = (int) mbstowcs(NULL, tmp, 0); if (nc >= 0) { wchar_t *wstr = Calloc(nc+1, wchar_t); mbstowcs(wstr, tmp, nc+1); for (wchar_t * wc = wstr; *wc; wc++) { if (*wc == L'.' || (allow_ && *wc == L'_')) /* leave alone */; else if (!iswalnum((int)*wc)) *wc = L'.'; } wcstombs(tmp, wstr, strlen(tmp)+1); Free(wstr); } else error(_("invalid multibyte string %d"), i+1); } else { for (p = tmp; *p; p++) { if (*p == '.' || (allow_ && *p == '_')) /* leave alone */; else if (!isalnum(0xff & (int)*p)) *p = '.'; /* else leave alone */ } }// l = (int) strlen(tmp); /* needed? */ SET_STRING_ELT(ans, i, mkChar(tmp)); /* do we have a reserved word? If so the name is invalid */ if (!isValidName(tmp)) { /* FIXME: could use R_Realloc instead */ cbuf = CallocCharBuf(strlen(tmp) + 1); strcpy(cbuf, tmp); strcat(cbuf, "."); SET_STRING_ELT(ans, i, mkChar(cbuf)); Free(cbuf); } Free(tmp); vmaxset(vmax); } UNPROTECT(1); return ans;}
As we can see, compiler-dependent datatypes such as wchar_t (http://icu-project.org/docs/papers/unicode_wchar_t.html) are used. This means that the behavior of make.names() depends on the C-compiler used to compile the R-interpreter itself. The problem is that C-compilers aren't very standardized therefore no assumption about the behavior of characters can be made. Everything including operating system, hardware, locale etc. can change this behavior.
In conclusion, I would stick to ASCII characters if you want to be save, especially when sharing your code between different operating systems.