[r] 특정 순서로 벡터에 따라 데이터 프레임 행 순서

아래 짧은 예에서 구현 한 것과 같이 “대상”벡터에 따라 데이터 프레임의 행이 정렬되도록하는 더 쉬운 방법이 있습니까?

df <- data.frame(name = letters[1:4], value = c(rep(TRUE, 2), rep(FALSE, 2)))

df
#   name value
# 1    a  TRUE
# 2    b  TRUE
# 3    c FALSE
# 4    d FALSE

target <- c("b", "c", "a", "d")

이것은 어떻게 든 일을 끝내기에는 너무 “복잡한”것 같습니다.

idx <- sapply(target, function(x) {
    which(df$name == x)
})
df <- df[idx,]
rownames(df) <- NULL

df
#   name value
# 1    b  TRUE
# 2    c FALSE
# 3    a  TRUE
# 4    d FALSE



답변

시도 match:

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")
df[match(target, df$name),]

  name value
2    b  TRUE
3    c FALSE
1    a  TRUE
4    d FALSE

그것은 한 당신이로 작동 target정확히 같은 요소를 포함 df$name하고, 둘은 중복 값을 포함하지 않습니다.

보낸 사람 ?match:

match returns a vector of the positions of (first) matches of its first argument
in its second.

따라서 의 요소 match와 일치하는 행 번호를 찾은 target다음 df순서대로 반환 합니다.


답변

내가 사용하는 것을 선호 ***_joindplyr나는 데이터와 일치해야 할 때마다. 이것에 대한 한 가지 가능한 시도

left_join(data.frame(name=target),df,by="name")

에 대한 입력 ***_join에는 tbls 또는 data.frame 이 필요합니다.


답변

이 방법은 약간 다르므로 이전 답변보다 약간 더 유연합니다. 그것을 주문 된 요소로 만들면 잘 사용할 수 있습니다 arrange. gdata패키지 에서 reorder.factor를 사용했습니다 .

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")

require(gdata)
df$name <- reorder.factor(df$name, new.order=target)

다음으로 지금 주문한다는 사실을 사용하십시오.

require(dplyr)
df %>%
  arrange(name)
    name value
1    b  TRUE
2    c FALSE
3    a  TRUE
4    d FALSE

원래 (알파벳) 순서로 as.character()돌아가려면 원래 상태로 되돌리려면 사용 하십시오.


답변

우리는 target그것을 기반으로 요인 수준을 조정 하고 사용할 수 있습니다arrange

library(dplyr)
df %>% arrange(factor(name, levels = target))

#  name value
#1    b  TRUE
#2    c FALSE
#3    a  TRUE
#4    d FALSE

아니면 order그것을 사용slice

df %>% slice(order(factor(name, levels = target)))


답변

라이브러리를 사용하지 않고 데이터에 재발하는 경우 which함께 사용할 수도 있습니다 sapply.

new_order <- sapply(target, function(x,df){which(df$name == x)}, df=df)
df        <- df[new_order,]


답변