문자열 벡터 입력을 사용하여 dplyr의 여러 열로 그룹화
플라이어에 대한 이해를 dplyr로 옮기려고 하는데, 여러 열로 그룹화하는 방법을 알 수가 없습니다.
# make data with weird column names that can't be hard coded
data = data.frame(
asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
# get the columns we want to average within
columns = names(data)[-3]
# plyr - works
ddply(data, columns, summarize, value=mean(value))
# dplyr - raises error
data %.%
group_by(columns) %.%
summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds
plyr 예제를 applyr-esque 구문으로 변환하려면 무엇이 부족합니까?
2017년 편집: Dplyr이 업데이트되었으므로 더 간단한 솔루션을 사용할 수 있습니다.현재 선택한 답변을 확인합니다.
코드 전체를 작성하기 위해, 해들리의 답변에 대한 새로운 구문을 업데이트합니다.
library(dplyr)
df <- data.frame(
asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
# Columns you want to group by
grp_cols <- names(df)[-3]
# Convert character vector to list of symbols
dots <- lapply(grp_cols, as.symbol)
# Perform frequency counts
df %>%
group_by_(.dots=dots) %>%
summarise(n = n())
출력:
Source: local data frame [9 x 3]
Groups: asihckhdoydk
asihckhdoydk a30mvxigxkgh n
1 A A 10
2 A B 10
3 A C 13
4 B A 14
5 B B 10
6 B C 12
7 C A 9
8 C B 12
9 C C 10
가 지정된 의 dplyr을 했습니다.group_by
(여기에 설명).이 기능을 사용하면 사용할 수 있는 것과 동일한 기능을 사용할 수 있습니다.select
예:
data = data.frame(
asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
# get the columns we want to average within
columns = names(data)[-3]
library(dplyr)
df1 <- data %>%
group_by_at(vars(one_of(columns))) %>%
summarize(Value = mean(value))
#compare plyr for reference
df2 <- plyr::ddply(data, columns, plyr::summarize, value=mean(value))
table(df1 == df2, useNA = 'ifany')
## TRUE
## 27
예제 질문의 출력은 예상대로입니다(위의 플라이어와 아래의 출력 비교 참조).
# A tibble: 9 x 3
# Groups: asihckhdoydkhxiydfgfTgdsx [?]
asihckhdoydkhxiydfgfTgdsx a30mvxigxkghc5cdsvxvyv0ja Value
<fctr> <fctr> <dbl>
1 A A 0.04095002
2 A B 0.24943935
3 A C -0.25783892
4 B A 0.15161805
5 B B 0.27189974
6 B C 0.20858897
7 C A 0.19502221
8 C B 0.56837548
9 C C -0.22682998
로 그이로후 이후로.dplyr::summarize
한 번에 그룹화의 한 층만 벗겨내면 결과적인 티블에서 여전히 그룹화가 진행되고 있습니다(때로는 나중에 깜짝 놀라 사람들을 잡을 수 있습니다). 여러분이 치 못한 그룹화 행동으로부터 으로 안전하기를 , 든지 예치않그기 동 다 완 있 추 수 언 니 습 할 가 지 든 제 면 보 려 하 안 은 호 게 하 전 룹 화 터 전 히 부 로 작 으 ▁always ▁if ▁add 다%>% ungroup
요약한 후 파이프라인으로 이동합니다.
이 공급업체에 대한 지원은 현재 매우 약하므로 구문은 다음과 같이 될 것으로 생각입니다.
df %.% group_by(.groups = c("asdfgfTgdsx", "asdfk30v0ja"))
하지만 그것은 아마 당분간은 없을 것입니다(모든 결과를 고려해야 하기 때문입니다).
에는 그동안, 은신당을 할 수 있습니다.regroup()
기호 목록을 사용합니다.
library(dplyr)
df <- data.frame(
asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
df %.%
regroup(list(quote(asihckhdoydk), quote(a30mvxigxkgh))) %.%
summarise(n = n())
당신이 열 벡터를 , 을 ▁names▁right▁if▁to,▁of▁you▁convert▁the다▁them▁vector있니습▁can열▁character▁you▁have▁column▁a▁have수변환과 함께 올바른 구조로 변환할 수 있습니다.lapply()
그리고.as.symbol()
:
vars <- setdiff(names(df), "value")
vars2 <- lapply(vars, as.symbol)
df %.% regroup(vars2) %.% summarise(n = n())
지열정자에 있는 열의 dplyr
는 제이 의 됩니다.dplyr
이름이 밑줄로 끝나는 함수입니다.를 들어, 예들어해에 하는 경우입니다.group_by
에는 기이있습다니능이 .group_by_
문자열 인수를 사용할 수 있는 함수입니다.이 Vignette는 이러한 기능의 구문에 대해 자세히 설명합니다.
제기했던 합니다. ( @sharoz @sharoz @sharoz ..dots
인수):
# Given data and columns from the OP
data %>%
group_by_(.dots = columns) %>%
summarise(Value = mean(value))
(dplyr은 이제 다음을 사용합니다.%>%
및 연자산, 리고그%.%
사용되지 않음).
dplyr 1.0.0에서 cross()로 업데이트
위의 모든 답변은 여전히 작동하고 있으며 .dots 인수가 있는 솔루션이 도움이 됩니다.
하지만 기억하기 쉬운 해결책을 찾는다면, 새로운 것은across()
도움이 됩니다.2020-04-03 Hadley Wickham에 의해 발행되었으며 다음에서 사용할 수 있습니다.mutate()
그리고.summarise()
그리고 다음과 같은 범위의 변형을 대체합니다._at
또는_all
무엇보다 번거로운 NSE(Non-Standard Evaluation)를 다음과 같은 견적/견적 해제로 매우 우아하게 대체합니다.!!! rlang::syms()
.
따라서 솔루션은 다음과 같습니다.across
가독성이 매우 좋아요.
data %>%
group_by(across(all_of(columns))) %>%
summarize(Value = mean(value))
dplyr이 문자열 인수를 완전히 지원할 때까지, 아마도 이 요지는 유용할 것입니다.
https://gist.github.com/skranz/9681509
여기에는 문자열 인수를 사용하는 s_group_by, s_mutate, s_filter 등과 같은 래퍼 함수의 묶음이 포함되어 있습니다.일반적인 dplyr 함수와 혼합할 수 있습니다.예를들면
cols = c("cyl","gear")
mtcars %.%
s_group_by(cols) %.%
s_summarise("avdisp=mean(disp), max(disp)") %.%
arrange(avdisp)
문자 벡터가 아닌 객체(그렇지는 않지만...)를 전달하면 작동합니다.
df %.%
group_by(asdfgfTgdsx, asdfk30v0ja) %.%
summarise(Value = mean(value))
> df %.%
+ group_by(asdfgfTgdsx, asdfk30v0ja) %.%
+ summarise(Value = mean(value))
Source: local data frame [9 x 3]
Groups: asdfgfTgdsx
asdfgfTgdsx asdfk30v0ja Value
1 A C 0.046538002
2 C B -0.286359899
3 B A -0.305159419
4 C A -0.004741504
5 B B 0.520126476
6 C C 0.086805492
7 B C -0.052613078
8 A A 0.368410146
9 A B 0.088462212
어디에df
당신의data
.
?group_by
다음과 같이 말합니다.
...: variables to group by. All tbls accept variable names, some
will also accept functons of variables. Duplicated groups
will be silently dropped.
내가 해석하는 것은 이름의 캐릭터 버전이 아니라, 당신이 그것들을 어떻게 언급할 것인지를 의미합니다.foo$bar
;bar
여기에 인용되지 않았습니다.공식에서 변수를 참조하는 방법:foo ~ bar
.
@Arun은 또한 다음과 같은 작업을 수행할 수 있다고 말합니다.
df %.%
group_by("asdfgfTgdsx", "asdfk30v0ja") %.%
summarise(Value = mean(value))
그러나 평가되지 않은 것이 데이터 개체의 변수 이름이 아닌 것은 전달할 수 없습니다.
이것은 해들리가 당신이 전달한 것들을 찾기 위해 사용하는 내부 방법 때문이라고 생각합니다....
논쟁.
data = data.frame(
my.a = sample(LETTERS[1:3], 100, replace=TRUE),
my.b = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
group_by(data,newcol=paste(my.a,my.b,sep="_")) %>% summarise(Value=mean(value))
여기서 답변에서 누락된 한 가지(작은) 사례는 그룹화할 변수가 파이프라인에서 미드스트림으로 동적으로 생성되는 경우입니다.
library(wakefield)
df_foo = r_series(rnorm, 10, 1000)
df_foo %>%
# 1. create quantized versions of base variables
mutate_each(
funs(Quantized = . > 0)
) %>%
# 2. group_by the indicator variables
group_by_(
.dots = grep("Quantized", names(.), value = TRUE)
) %>%
# 3. summarize the base variables
summarize_each(
funs(sum(., na.rm = TRUE)), contains("X_")
)
기본적으로 사용 방법을 보여줍니다.grep
와 함께group_by_(.dots = ...)
이를 위해
사용에 대한 일반적인 예.dots
문자 벡터 입력으로서의 인수dplyr::group_by
함수:
iris %>%
group_by(.dots ="Species") %>%
summarise(meanpetallength = mean(Petal.Length))
또는 OP의 요청에 따라 그룹화 변수에 대한 하드 코딩된 이름 없이:
iris %>%
group_by(.dots = names(iris)[5]) %>%
summarise_at("Petal.Length", mean)
OP의 예와 함께:
data %>%
group_by(.dots =names(data)[-3]) %>%
summarise_at("value", mean)
대명사, 준인용 부호, 인수 및 조석 값을 설명하는 프로그래밍에 대한 dplyrvignett도 참조하십시오.
언급URL : https://stackoverflow.com/questions/21208801/group-by-multiple-columns-in-dplyr-using-string-vector-input
'programing' 카테고리의 다른 글
Content-Type 헤더에 관계없이 Python Flask에서 원시 POST 본문 가져오기 (0) | 2023.07.17 |
---|---|
C 표준 라이브러리의 위치 (0) | 2023.07.17 |
파이썬 멀티프로세싱 모듈의 .join() 메서드는 정확히 무엇을 하고 있습니까? (0) | 2023.07.17 |
Android Studio 오류 "Android Gradle 플러그인을 실행하려면 Java 11이 필요합니다.현재 Java 1을 사용하고 있습니다.8" (0) | 2023.07.17 |
Nux JS에서 Vuex 모듈 모드를 올바르게 사용하는 방법은 무엇입니까? (0) | 2023.07.17 |