R将行汇总到一行(连续和因子变量)

时间:2015-07-17 07:15:22

标签: r dplyr

我正在尝试将一堆行累积成一行。如果可能的话,我希望在dplyr中。我知道我的代码远非正确,但这是我得到了多远:

data %>%
  group_by(DAY) %>%
  summarise_each(funs(Sum = n()), SEX, GROUP, TOTAL)

原件:

DAY SEX GROUP   TOTAL       
7/1/14  FEMALE  A   1       
7/1/14  FEMALE  B   1       
7/1/14  FEMALE  B   1       
7/1/14  FEMALE  A   1       
7/1/14  MALE    A   1       
7/1/14  MALE    B   2       

新:

DAY     FEMALE  MALE    GROUP_A GROUP_B TOTAL
7/1/14  4       2       3       3       7  

4 个答案:

答案 0 :(得分:8)

使用data.table的另一种方式,在data.frame上测试超过一天。

require(data.table)
setDT(data)[, as.list(c(table(SEX), table(GROUP), TOTAL=sum(TOTAL))), by=DAY]

#      DAY FEMALE MALE A B TOTAL
#1: 7/1/14      3    0 1 2     3
#2: 8/1/14      1    2 2 1     4

编辑:另一个不那么手动的选项(你不需要知道哪些变量是因素,哪些是数字),感谢@jangorecki和@DavidArenburg的一些帮助

wh_num <- sapply(data, is.numeric)[-1]
wh_fact <-sapply(data, is.factor)[-1]
setDT(data)[, as.list(c(lapply(.SD[, wh_fact, with = FALSE], table), 
                        lapply(.SD[, wh_num, with = FALSE], sum), 
                        recursive = TRUE)), by = DAY]

#      DAY SEX.FEMALE SEX.MALE GROUP.A GROUP.B TOTAL
#1: 7/1/14          3        0       1       2     3
#2: 8/1/14          1        2       2       1     4

数据

data <- structure(list(DAY = c("7/1/14", "7/1/14", "7/1/14", "8/1/14", 
"8/1/14", "8/1/14"), SEX = structure(c(1L, 1L, 1L, 1L, 2L, 2L
), .Label = c("FEMALE", "MALE"), class = "factor"), GROUP = structure(c(1L, 
2L, 2L, 1L, 1L, 2L), .Label = c("A", "B"), class = "factor"), 
    TOTAL = c(1L, 1L, 1L, 1L, 1L, 2L)), .Names = c("DAY", "SEX", 
"GROUP", "TOTAL"), row.names = c(NA, -6L), class = "data.frame")

答案 1 :(得分:5)

它可能看起来有点神秘,但这是一个短暂的咒语

In [219]: A = pd.Series([np.nan, np.nan, np.nan, 1, 2, np.nan, 3])

In [220]: A
Out[220]: 
0   NaN
1   NaN
2   NaN
3     1
4     2
5   NaN
6     3
dtype: float64

In [221]: A[np.where(~np.isnan(A))[0][0]:]       # Approach 1
Out[221]: 
3     1
4     2
5   NaN
6     3
dtype: float64

In [222]: A[np.maximum.accumulate(~np.isnan(A))]  # Approach 2
Out[222]: 
3     1
4     2
5   NaN
6     3
dtype: float64

在这里,您只需将每列列为表格(如果它不是数字),或者将其汇总(如果是)(对于总列)。这需要作为列表返回,因为dat %>% group_by(DAY) %>% summarise_each(funs(ifelse(is.numeric(.), sum(.), list(table(.))))) -> res data.frame(DAY=res$DAY, t(unlist(res[, 2:ncol(res)]))) # DAY SEX.FEMALE SEX.MALE GROUP.A GROUP.B TOTAL # 1 7/1/14 4 2 3 3 7 需要单个值。然后,结果将扩展为常规summarise_each

答案 2 :(得分:3)

计算总数(总和)和其他列(表)的方式差别很大,因此您可能需要单独执行这些步骤。计算总数很容易。对于制表,我建议使用tidyr,如下所示:

# required packages
require(dplyr)
require(tidyr)

# calculations
data %>%
  group_by(DAY) %>%                     # group by day
  mutate(TOTAL = sum(TOTAL)) %>%        # first calculate total
  gather(key, value, -DAY, -TOTAL) %>%  # collapse
  unite(group, key, value) %>%          # get sensible column names
  group_by(DAY, TOTAL) %>%              # group by day and total
  do(as.data.frame(table(.$group))) %>% # table
  spread(Var1, Freq)                    # spread out

##      DAY TOTAL GROUP_A GROUP_B SEX_FEMALE SEX_MALE
## 1 7/1/14     7       3       3          4        2

答案 3 :(得分:3)

一种可能的方法:

library(reshape2)
library(data.table)

cbind(dcast(df, DAY~SEX), 
      dcast(df, DAY~GROUP)[-1], 
      setDT(df)[,.(total=sum(TOTAL)),DAY][,-1,with=F])

#     DAY FEMALE MALE A B total
#1 7/1/14      4    2 3 3     7