R에서 문자열 만들기
R의 문자열은 따옴표 사이의 텍스트입니다. 큰따옴표와 작은따옴표 모두 동작하며 의미도 정확히 같습니다. 관례는 큰따옴표를 쓰되, 텍스트 자체에 큰따옴표가 들어 있으면 작은따옴표로 바꾸는 것입니다.
역슬래시 이스케이프는 대부분의 언어와 같습니다. 따옴표 문자에는 \", 줄바꿈에는 \n, 탭에는 \t, 역슬래시 자체에는 \\를 씁니다.
이제 모든 R 입문자가 정확히 한 번씩 저지르는 실수입니다. length()로 문자열의 길이를 묻는 것이죠.
nchar()는 문자를 세어 5를 줍니다. length()는 벡터 원소를 세는데 문자열 하나는 원소가 하나인 벡터이므로 1이라고 답합니다. R에서는 텍스트를 포함해 모든 것이 벡터이며, 이 페이지의 모든 함수는 문자 벡터 전체에 대해 조용히 원소 단위로 동작합니다. 놀라지 않게 되고 나면 이것은 장점입니다.
문자열 붙이기: paste()와 paste0()
R에는 문자열용 +가 없습니다. 연결은 기본적으로 인자들을 공백으로 잇는 paste()와, 아무것도 넣지 않고 잇는 paste0()가 담당합니다.
paste는 벡터화되어 있으므로 벡터를 넘기면 여러 문자열을 한 번에 만듭니다. 파일 이름, 라벨, ID를 한 줄로 생성하는 방법입니다.
그리고 collapse 인자는 반대 일을 합니다. 벡터 전체를 선택한 구분자로 이어 하나의 문자열로 융합합니다.
구분을 기억하세요. sep은 인자들 사이의 접착제이고 collapse는 한 벡터의 원소들 사이의 접착제입니다. 한 호출에서 둘 다 쓸 수 있습니다.
sprintf()로 서식 지정하기
텍스트 안에 숫자를 서식에 맞춰 넣어야 할 때, 즉 소수 자릿수를 고정하거나 폭을 채워야 할 때 paste()는 힘이 빠지고 sprintf()가 나섭니다. C 스타일 서식 코드를 사용합니다. 문자열에는 %s, 정수에는 %d, 소수에는 %f입니다.
%.1f는 "소수 한 자리", %.3f는 세 자리를 뜻하고, %05d는 0으로 채워 다섯 자리를 만듭니다. %%를 두 번 쓰면 퍼센트 기호 자체가 출력됩니다. sprintf()도 벡터화되어 있어 값의 열 전체를 한 번의 호출로 서식화할 수 있습니다. sprintf() + cat() 보고 패턴은 입력과 출력을 참고하세요.
대소문자 바꾸기와 잘라 내기: toupper(), tolower(), substr()
대소문자 변환은 이름 그대로입니다.
tolower()는 비교 전에 지저분한 데이터를 정규화할 때 제 몫을 합니다. "Yes", "YES", "yes"가 모두 같은 값이 됩니다.
substr(x, start, stop)은 1부터 세는 문자 위치로 부분 문자열을 추출합니다(R은 어디서나 1부터 시작합니다).
양쪽 끝 모두 포함됩니다. 1부터 11까지의 위치는 "Programming"을 줍니다.
찾아 바꾸기: sub(), gsub(), grepl()
sub()는 패턴이 처음 나타난 곳을 바꾸고, gsub()("global substitute")는 모든 곳을 바꿉니다.
중요한 세부 사항이 하나 있습니다. 패턴은 기본적으로 문자 그대로의 텍스트가 아니라 정규표현식입니다. ., *, (, ? 같은 정규식 문자는 특별한 의미를 가지며, 아무 수식 없는 .은 어떤 문자와도 일치합니다. 문자 그대로를 의도한다면 fixed = TRUE를 전달하세요.
첫 줄은 a-b-c를 주고, 두 번째 줄은 -----를 줍니다. 정규식으로서 .이 모든 문자와 일치했기 때문입니다. 정규식을 익히기 전까지는 fixed = TRUE를 기본으로 삼으면 당할 일이 없습니다.
grepl()은 바꾸지 않습니다. 각 원소가 일치하는지 검사해 논리 벡터를 돌려줍니다. 그래서 텍스트 필터링의 표준 도구입니다.
첫 결과는 어떤 파일 이름에 .csv가 들어 있는지 표시하고, 두 번째는 그 논리 벡터를 이용해 일치하는 것만 남깁니다.
분리하기와 다듬기: strsplit()와 trimws()
strsplit()는 구분자를 기준으로 문자열을 잘라 냅니다. 한 가지 특이한 점은 여러 문자열을 한 번에 분리할 수 있기 때문에 리스트를 돌려준다는 것입니다. 문자열 하나라면 [[1]]로 첫 원소를 가져오세요.
그리고 trimws()는 실제 데이터가 늘 두르고 오는 공백을 제거합니다.
기본적으로 양쪽 끝을 다듬고, which = "left"나 "right"를 주면 한쪽만 다듬습니다(이름은 문자열의 시작과 끝을 가리킵니다).
stringr라는 대안
위의 모든 것은 기본 R이며, 설치 없이 언제나 사용할 수 있습니다. tidyverse의 stringr 패키지는 같은 연산들을 일관된 str_* 명명 규칙으로 감싸고 문자열을 항상 첫 인자로 둡니다. 많은 사람이 이 쪽을 기억하기 쉽다고 느낍니다(설치는 패키지 참고).
library(stringr)
str_detect(files, "csv") # like grepl(), data first
str_replace_all(s, "good", "great") # like gsub(), arguments reordered
str_length("hello") # like nchar()
그럼에도 기본 R의 문자열 함수는 알아 둘 가치가 있습니다. 지금까지 쓰인 모든 스크립트, Stack Overflow 답변, 오류 메시지에서 만나게 되기 때문입니다. 기본 이름들을 먼저 익히고, 일관성 없는 인자 순서가 거슬리기 시작하면 stringr을 도입하세요.
핵심 정리
- 문자열은 관례상 큰따옴표를 씁니다.
nchar()는 문자를 세고length()는 벡터 원소를 셉니다. paste()/paste0()로 연결합니다.sep은 인자들을,collapse는 벡터를 하나의 문자열로 잇습니다.sprintf()는 서식 있는 출력을 담당합니다.%s,%d,%.2f를 사용합니다.sub()는 첫 일치를,gsub()는 모든 일치를 바꾸고grepl()은 일치 여부를 검사합니다. 모두 기본이 정규식이므로 문자 그대로를 원하면fixed = TRUE를 전달하세요.strsplit()는 리스트를 돌려주므로[[1]]을 꺼내고,trimws()는 공백이 덧붙은 입력을 정리합니다.
다음 순서는 프로그램에 텍스트를 넣고 빼는 방법입니다. print()와 cat()으로 출력하고 사용자 입력을 읽는 법을 다룹니다.
자주 묻는 질문
R에서 문자열을 어떻게 연결하나요?
paste()나 paste0()를 사용합니다. R에는 문자열용 +가 없습니다. paste("data", "science")는 "data science"를 주고(기본 구분자는 공백), paste0("data", "science")는 아무것도 넣지 않고 붙입니다. 구분자를 바꾸려면 sep =을, 벡터 전체를 하나의 문자열로 합치려면 collapse =을 사용하세요.
R에서 문자열의 길이는 어떻게 구하나요?
nchar("hello")는 문자 개수인 5를 돌려줍니다. length("hello")는 1을 돌려주는데, R에서 length()는 벡터의 원소 개수를 세고 문자열 하나는 원소가 하나인 벡터이기 때문입니다. length()와 nchar()를 헷갈리는 것은 입문자의 전형적인 실수입니다.
R에서 sub()와 gsub()의 차이는 무엇인가요?
둘 다 찾아 바꾸지만, sub()는 첫 번째 일치만 바꾸고 gsub()("global sub")는 모든 일치를 바꿉니다. 둘 다 기본적으로 패턴을 정규표현식으로 취급하므로, 문자 그대로 매칭하려면 fixed = TRUE를 전달하세요.
R에서 문자열을 어떻게 분리하나요?
strsplit(x, split)이 패턴을 기준으로 분리하지만, 여러 문자열을 한 번에 분리할 수 있기 때문에 리스트를 돌려줍니다. 문자열 하나라면 첫 원소를 꺼내세요. strsplit("a,b,c", ",")[[1]]은 문자 벡터 "a" "b" "c"를 줍니다.