R에서 루프를 피하는 방법 : 목록에서 항목 선택
문제
루프를 사용하여 이것을 해결할 수는 있지만 벡터를 생각하려고 노력하고 있으므로 코드가 더 r-esque가 될 것입니다.
이름 목록이 있습니다. 형식은 FirstName_lastName입니다. 이 목록에서 이름 만있는 별도의 목록을 얻고 싶습니다. 나는 이것을하는 방법에 대해 내 마음을 얻을 수없는 것 같다. 몇 가지 예 데이터는 다음과 같습니다.
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- strsplit(t,"_")
다음과 같이 보입니다.
> tsplit
[[1]]
[1] "bob" "smith"
[[2]]
[1] "mary" "jane"
[[3]]
[1] "jose" "chung"
[[4]]
[1] "michael" "marx"
[[5]]
[1] "charlie" "ivan"
다음과 같은 루프를 사용하고 싶은 것을 얻을 수 있습니다.
for (i in 1:length(tsplit)){
if (i==1) {t_out <- tsplit[[i]][1]} else{t_out <- append(t_out, tsplit[[i]][1])}
}
나에게 이것을 줄 것이다 :
t_out
[1] "bob" "mary" "jose" "michael" "charlie"
루프없이 어떻게 할 수 있습니까?
해결책
당신이 사용할 수있는 apply
(또는 sapply
)
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
f <- function(s) strsplit(s, "_")[[1]][1]
sapply(t, f)
bob_smith mary_jane jose_chung michael_marx charlie_ivan
"bob" "mary" "jose" "michael" "charlie"
다른 팁
그리고 한 가지 더 접근 :
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
pieces <- strsplit(t,"_")
sapply(pieces, "[", 1)
말로, 마지막 줄은 목록의 각 구성 요소의 첫 번째 요소를 추출한 다음 벡터로 단순화합니다.
이것은 어떻게 작동합니까? 글쎄, 당신은 대안적인 글쓰기 방법을 실현해야합니다 x[1]
~이다 "["(x, 1)
, 즉, 호출되는 함수가 있습니다 [
그것은 하위 집합을합니다. 그만큼 sapply
Call은 원래 목록의 각 요소에 대해이 기능을 한 번, 두 개의 인수, 목록 요소와 1을 전달합니다.
다른 접근법에 비해이 접근법의 장점은 스플릿을 재편 처리하지 않고도 목록에서 여러 요소를 추출 할 수 있다는 것입니다. 예를 들어, 성은입니다 sapply(pieces, "[", 2)
. 이 관용구에 익숙해지면 읽기가 매우 쉽습니다.
어때요 :
tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
fnames <- gsub("(_.*)$", "", tlist)
# _.* matches the underscore followed by a string of characters
# the $ anchors the search at the end of the input string
# so, underscore followed by a string of characters followed by the end of the input string
REGEX 접근법을 위해?
는 어때:
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
sub("_.*", "", t)
이것이 가장 우아한 솔루션이지만 루핑을 능가합니다.
t.df <- data.frame(tsplit)
t.df[1, ]
목록을 데이터 프레임으로 변환하는 것은 내가 원하는 것을 할 수있는 유일한 방법입니다. 실제로 목록을 처리하는 방법을 이해하는 사람들의 답변을 읽기를 고대하고 있습니다.
당신은 거의 그것을 가지고있었습니다. 그것 진짜 단지 문제입니다
- 하나를 사용합니다
*apply
기존 목록을 통해 루프하는 기능, 종종 시작합니다.lapply
그리고 때로는 전환합니다sapply
- 한 번에 목록 요소 중 하나에서 작동하는 익명 함수 추가
- 당신은 이미 그것을 알고있었습니다
strsplit(string, splitterm)
그리고 당신은 홀수가 필요합니다[[1]][1]
답의 첫 번째 용어를 선택합니다 - 선호하는 변수 namne부터 시작하여 모든 것을 합치십시오 (우리는
t
또는c
그리고 친구들)
주는 것
> tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> fnames <- sapply(tlist, function(x) strsplit(x, "_")[[1]][1])
> fnames
bob_smith mary_jane jose_chung michael_marx charlie_ivan
"bob" "mary" "jose" "michael" "charlie"
>
당신은 사용할 수 있습니다 unlist()
:
> tsplit <- unlist(strsplit(t,"_"))
> tsplit
[1] "bob" "smith" "mary" "jane" "jose" "chung" "michael"
[8] "marx" "charlie" "ivan"
> t_out <- tsplit[seq(1, length(tsplit), by = 2)]
> t_out
[1] "bob" "mary" "jose" "michael" "charlie"
홀수-인덱스 항목 만 꺼내는 더 나은 방법이있을 수 있지만 어쨌든 루프가 없을 것입니다.
그리고 Brentonk의 unlist 예제를 기반으로 한 다른 접근법 ...
tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- unlist(strsplit(tlist,"_"))
fnames <- tsplit[seq(1:length(tsplit))%%2 == 1]
다음 Unlist ()-기반 방법을 사용합니다.
> t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> tsplit <- strsplit(t,"_")
>
> x <- matrix(unlist(tsplit), 2)
> x[1,]
[1] "bob" "mary" "jose" "michael" "charlie"
이 방법의 가장 큰 장점은 성의 동일한 문제를 동시에 해결한다는 것입니다.
> x[2,]
[1] "smith" "jane" "chung" "marx" "ivan"
단점은 모든 이름이 firstname_lastname
구조; 그렇지 않으면이 방법이 깨질 것입니다.
원본에서 tsplit
처음에 주어진 개체를 목록하면이 명령은 다음을 수행합니다.
unlist(lapply(tsplit,function(x) x[1]))
모든 목록 요소의 첫 번째 요소를 추출한 다음 목록을 벡터로 변환합니다. 먼저 매트릭스에 미치지 못하면 주먹 열을 추출하는 것도 괜찮지 만 모든 목록 요소가 같은 길이를 가지고 있다는 사실에 의존합니다. 출력은 다음과 같습니다.
> tsplit
[[1]]
[1] "bob" "smith"
[[2]]
[1] "mary" "jane"
[[3]]
[1] "jose" "chung"
[[4]]
[1] "michael" "marx"
[[5]]
[1] "charlie" "ivan"
> lapply(tsplit,function(x) x[1])
[[1]]
[1] "bob"
[[2]]
[1] "mary"
[[3]]
[1] "jose"
[[4]]
[1] "michael"
[[5]]
[1] "charlie"
> unlist(lapply(tsplit,function(x) x[1]))
[1] "bob" "mary" "jose" "michael" "charlie"