聚合包含数字和字符串的列

时间:2016-04-11 17:52:41

标签: r aggregate dplyr reshape

我的R脚本中有一个数据框,如下所示:

ID      B     C
1539   Blue   8
1539   Blue   4
1539   Red    9
1539   Red    13
1539   Yellow NCAA
3574   Green  RA
3574   Green  RA
3574   Green  RA
3574   Red    1 
3574   Red    1

如何聚合列C并转换数据集,使其如下所示:

  ID     Blue    Yellow    Green   Red    
  1539   12      NCAA       -      22
  3574   -       -          3RA    2     

如果值是C列中的一个因素,我基本上想要总结数字并计算。任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:3)

R中的列不能同时包含不同的类,因此您在列C中确实没有数字 - 它们是charactersfactors。我们可能需要确保它们是character,以便我们可以对它们应用type.convert。此外,factor具有integer存储模式 - 因此可能会让人感到困惑。之后,我们可以根据您的要求创建一个辅助函数,并将数据转换为宽格式。以下是使用data.table

的示例
library(data.table)
setDT(data1)[, C := as.character(C)] # Make sure it's a character column

# Define the function
f <- function(x) if(is.numeric(x <- type.convert(x))) {
                      as.character(sum(x)) 
                    } else paste0(length(x), x) 

# Rehsape
dcast(data1, ID ~ B, value.var = "C", f)
#      ID Blue Green Red Yellow
# 1: 1539   12     0  22  1NCAA
# 2: 3574    0   3RA   2      0

答案 1 :(得分:0)

您使用tidyrdplyr执行此操作,主要使用两个步骤:

  • spreadtidyr)创建新列,其中B中的名称和C中的值
  • group_by您的ID列,然后summarize_each剩下的列(dplyr),其中包含自定义摘要功能,以处理字符或数字列

这是完整的解决方案,需要更多的记录命令。

1。传播。传播的一个问题是所有行都必须在某些列(see here

中具有唯一的ID
library(dplyr)
library(tidyr)

## spread with 'convert' will convert types automatically

spread_data <- dat %>%
  mutate(row= 1:nrow(dat)) %>% ## uniquely id rows
  spread(B, C, convert = TRUE) %>%
  select(-row)

## converting the data.frame to a tbl_df
## lets us easily see the cols are different types
tbl_df(spread_data)    
##Source: local data frame [10 x 5]
##
##      ID  Blue Green   Red Yellow
##   (int) (int) (chr) (int)  (chr)
##   1   1539     8    NA    NA     NA
##   2   1539     4    NA    NA     NA
##   3   1539    NA    NA     9     NA
##   4   1539    NA    NA    13     NA
##   5   1539    NA    NA    NA   NCAA
##   6   3574    NA    RA    NA     NA
##   7   3574    NA    RA    NA     NA
##   8   3574    NA    RA    NA     NA
##   9   3574    NA    NA     1     NA
##   10  3574    NA    NA     1     NA

2。分组并总结。首先,我们需要编写一个能处理任何一种列的函数

summarizer <- function(x) {
  if (is.numeric(x)) {
    sum(x, na.rm = TRUE)
  } else {
    # assume x is a character
    if (all(is.na(x)))
      return("-")
    x[is.na(x)] <- ""
    x <- unique(x)
    paste0(x, collapse="")
  }
}

## summarize each applies summarizer to the columns that aren't being used
## for grouping (so, not ID in this case)
spread_data %>% group_by(ID) %>%
  summarize_each(funs(summarizer))
##Source: local data frame [2 x 5]
##
##     ID  Blue Green   Red Yellow
##  (int) (int) (chr) (int)  (chr)
##  1  1539    12     -    22   NCAA
##  2  3574     0    RA     2      -