【问题标题】:summarizing data frame by columns in R在R中按列汇总数据帧
【发布时间】:2016-11-15 21:06:09
【问题描述】:

我有这个数据框 df:

df <- structure(list(App = structure(c(4L, 4L, 3L, 3L, 2L, 2L, 1L), .Label = c("DB", 
"End", "Mid", "Web"), class = "factor"), Server = structure(c(5L, 
6L, 1L, 2L, 3L, 4L, 7L), .Label = c("GServer101", "Hserver103", 
"JServer100", "Kserver200", "Server101", "Server102", "Xdb101"
), class = "factor"), Process1 = c(1L, 5L, 1L, 1L, 1L, 1L, 1L
), Process2 = c(1L, 1L, 1L, 4L, 1L, 1L, 1L), Process3 = c(NA, 
NA, NA, NA, NA, NA, NA), Process4 = c(NA, NA, NA, NA, NA, NA, 
NA), Process5 = c(NA, NA, NA, 1L, 1L, 1L, 1L)), .Names = c("App", 
"Server", "Process1", "Process2", "Process3", "Process4", "Process5"
), class = "data.frame", row.names = c(NA, -7L))

我希望能够总结 df 数据框并按列计数和放置过程,如下所示。我需要知道每个应用程序按列名分组的进程数。我将如何在 R 中做到这一点?

end <- structure(list(App = structure(c(4L, 3L, 2L, 1L), .Label = c("DB", 
"End", "Mid", "Web"), class = "factor"), Process1 = c(6L, 2L, 
2L, 1L), Process2 = c(2L, 5L, 2L, 1L), Process3 = c(0L, 0L, 0L, 
0L), Process4 = c(0L, 0L, 0L, 0L), Process5 = c(0L, 1L, 2L, 1L
)), .Names = c("App", "Process1", "Process2", "Process3", "Process4", 
"Process5"), class = "data.frame", row.names = c(NA, -4L))

【问题讨论】:

    标签: r dataframe summary


    【解决方案1】:

    你可以使用dplyr:

    library(dplyr)
    df %>% 
          group_by(App) %>% 
          summarize_at(vars(starts_with("Process")), funs(sum(., na.rm=TRUE)))
    
    # A tibble: 4 × 6
    #     App Process1 Process2 Process3 Process4 Process5
    #  <fctr>    <int>    <int>    <int>    <int>    <int>
    #1     DB        1        1        0        0        1
    #2    End        2        2        0        0        2
    #3    Mid        2        5        0        0        1
    #4    Web        6        2        0        0        0
    

    或者如果首选列位置,可以将位置传递给.cols参数:

    df %>% 
           group_by(App) %>% 
           summarize_at(.cols=3:7, funs(sum(., na.rm=TRUE)))
    
    # A tibble: 4 × 6
    #     App Process1 Process2 Process3 Process4 Process5
    #  <fctr>    <int>    <int>    <int>    <int>    <int>
    #1     DB        1        1        0        0        1
    #2    End        2        2        0        0        2
    #3    Mid        2        5        0        0        1
    #4    Web        6        2        0        0        0
    

    【讨论】:

    • 我收到此错误:找不到函数“summarize_at”
    • 你可能使用的是旧版本的dplyr,最新版本中引入了summarize_at()功能。
    • 另外,如果列名不以 process 开头,我将如何修改它,假设我想在列 2:7 上执行此操作?
    • 您可以将位置向量传递给.cols参数,请参阅更新。
    • 对不起,我太快接受这个答案。我正在使用您的代码,但在处理后我确实看到了多个 App 实例。每个应用程序应该只有一行。我们如何确保这一点?我验证了拼写是准确的。
    【解决方案2】:

    这是一个使用data.table的方法

    library(data.table)
    # convert df to data.table
    setDT(df)
    
    df[, lapply(.SD, sum, na.rm=TRUE), .SDcols=Process1:Process5, by="App"]
       App Process1 Process2 Process3 Process4 Process5
    1: Web        6        2        0        0        0
    2: Mid        2        5        0        0        1
    3: End        2        2        0        0        2
    4:  DB        1        1        0        0        1
    

    或者使用列位置而不是列名

    df[, lapply(.SD, sum, na.rm=TRUE), .SDcols=3:7, by="App"]
       App Process1 Process2 Process3 Process4 Process5
    1: Web        6        2        0        0        0
    2: Mid        2        5        0        0        1
    3: End        2        2        0        0        2
    4:  DB        1        1        0        0        1
    

    如果这是新的,这里有一个快速分解。 lapply(.SD, sum, na.rm=TRUE) 表示 sum 与所有列的 na.rm=TRUE,.SDcols=3:7.SDcols=Process1:Process5 将此操作子集到所需的列,by=App 将操作分组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-23
      • 2015-03-31
      • 1970-01-01
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      相关资源
      最近更新 更多