IT이야기

각 그룹 내에서 하나의 쉼표로 구분된 문자열로 열 축소/연결/집계

cyworld 2021. 10. 13. 20:40
반응형

각 그룹 내에서 하나의 쉼표로 구분된 문자열로 열 축소/연결/집계


두 그룹화 변수에 따라 데이터 프레임의 한 열을 집계하고 개별 값을 쉼표로 구분하고 싶습니다.

다음은 일부 데이터입니다.

data <- data.frame(A = c(rep(111, 3), rep(222, 3)), B = rep(1:2, 3), C = c(5:10))
data
#     A B  C
# 1 111 1  5
# 2 111 2  6
# 3 111 1  7
# 4 222 2  8
# 5 222 1  9
# 6 222 2 10    

"A"와 "B"는 그룹화 변수이고 "C"는 쉼표로 구분된 character문자열 로 축소하려는 변수입니다 . 나는 시도했다:

library(plyr)
ddply(data, .(A,B), summarise, test = list(C))

    A B  test
1 111 1  5, 7
2 111 2     6
3 222 1     9
4 222 2 8, 10

그러나 테스트 열을 변환하려고 character하면 다음과 같이됩니다.

ddply(data, .(A,B), summarise, test = as.character(list(C)))
#     A B     test
# 1 111 1  c(5, 7)
# 2 111 2        6
# 3 222 1        9
# 4 222 2 c(8, 10)

character형식을 유지하고 쉼표로 구분하려면 어떻게 해야 합니까? 예를 들어, 행 1은 "5,7"c(5,7) 이 아니라 오직 이어야 합니다 .


다음은 toString문자열을 쉼표로 연결하는 유용한 유틸리티 기능을 사용하는 몇 가지 옵션 입니다. 쉼표를 원하지 않으면 대신 인수 paste()와 함께 사용할 수 있습니다 collapse.

데이터.테이블

# alternative using data.table
library(data.table)
as.data.table(data)[, toString(C), by = list(A, B)]

집계 이것은 패키지를 사용하지 않습니다:

# alternative using aggregate from the stats package in the core of R
aggregate(C ~., data, toString)

SQLDF

다음은 sqldf 패키지group_concat사용하여 SQL 함수 사용하는 대안입니다 .

library(sqldf)
sqldf("select A, B, group_concat(C) C from data group by A, B", method = "raw")

dplyrdplyr대안 :

library(dplyr)
data %>%
  group_by(A, B) %>%
  summarise(test = toString(C)) %>%
  ungroup()

플라이어

# plyr
library(plyr)
ddply(data, .(A,B), summarize, C = toString(C))

입력 위치 변경 as.character:

> out <- ddply(data, .(A, B), summarise, test = list(as.character(C)))
> str(out)
'data.frame':   4 obs. of  3 variables:
 $ A   : num  111 111 222 222
 $ B   : int  1 2 1 2
 $ test:List of 4
  ..$ : chr  "5" "7"
  ..$ : chr "6"
  ..$ : chr "9"
  ..$ : chr  "8" "10"
> out
    A B  test
1 111 1  5, 7
2 111 2     6
3 222 1     9
4 222 2 8, 10

그러나 각 항목은 실제로 단일 문자열이 아닌 별도의 문자입니다. 즉, 이것은 "5, 7"처럼 보이는 실제 문자열이 아니라 R이 그 사이에 쉼표를 사용하여 표시하는 "5"와 "7"의 두 문자입니다.

다음과 비교하십시오.

> out2 <- ddply(data, .(A, B), summarise, test = paste(C, collapse = ", "))
> str(out2)
'data.frame':   4 obs. of  3 variables:
 $ A   : num  111 111 222 222
 $ B   : int  1 2 1 2
 $ test: chr  "5, 7" "6" "9" "8, 10"
> out
    A B  test
1 111 1  5, 7
2 111 2     6
3 222 1     9
4 222 2 8, 10

기본 R에서 비교 가능한 솔루션은 물론 다음과 aggregate같습니다.

> A1 <- aggregate(C ~ A + B, data, function(x) c(as.character(x)))
> str(A1)
'data.frame':   4 obs. of  3 variables:
 $ A: num  111 222 111 222
 $ B: int  1 1 2 2
 $ C:List of 4
  ..$ 0: chr  "5" "7"
  ..$ 1: chr "9"
  ..$ 2: chr "6"
  ..$ 3: chr  "8" "10"
> A2 <- aggregate(C ~ A + B, data, paste, collapse = ", ")
> str(A2)
'data.frame':   4 obs. of  3 variables:
 $ A: num  111 222 111 222
 $ B: int  1 1 2 2
 $ C: chr  "5, 7" "9" "6" "8, 10"

stringr/ tidyverse솔루션 은 다음과 같습니다 .

library(tidyverse)
library(stringr)

data <- data.frame(A = c(rep(111, 3), rep(222, 3)), B = rep(1:2, 3), C = c(5:10))


data %>%
 group_by(A, B) %>%
 summarize(text = str_c(C, collapse = ", "))

# A tibble: 4 x 3
# Groups:   A [2]
      A     B test 
  <dbl> <int> <chr>
1   111     1 5, 7 
2   111     2 6    
3   222     1 9    
4   222     2 8, 10

ReferenceURL : https://stackoverflow.com/questions/15933958/collapse-concatenate-aggregate-a-column-to-a-single-comma-separated-string-w

반응형