【问题标题】:Add every five lines in the column then divide by ten?将列中的每五行相加然后除以十?
【发布时间】:2015-05-08 21:47:01
【问题描述】:

我在 R 文件中有三列,看起来像这样;

X61253 X61613 X66198
279    140    140
279    139    139
278    139    139
279    140    140
279    139    139
278    139    139
3624   140    140
279    139    139
279    139    139
7730   140    140
278    139    139
12180  139    139
279   3660   3660
279    140    140
15443  139    139
278    139    139
18108 5527   5164
279    140    140

我想通过以下方式转换此数据; 每列的每 5 行(单独)求和,然后除以 10。

期望的输出;

 X61253,X61613,X66198
 139.4,69.7,69.7
 1219,69.7,69.7
 2845.9,421.7,421.7

使用 Excel 公式=sum(1:5)/10, =sum(6:10)/10, =sum(11:15)/10

【问题讨论】:

    标签: r excel csv


    【解决方案1】:

    一种解决方案:

    library("plyr")
    ss <- seq(0,nrow(x)-1)%/%5         ## grouping variable
    dd <- ddply(x,.(ss),colSums)/10
    

    根据大众需求,仅使用基础 R:

    dfs <- split(x,ss)  ## ss as constructed above
    do.call(rbind,lapply(dfs,colSums))/10
    

    也可以使用dplyrdata.table ...

    【讨论】:

    • Ben,由于某种原因,我无法在我的 RStudio 上安装 plyr 包 - 还有其他更简单的方法吗?
    【解决方案2】:

    在需要推广rowsum(plafort的“df”):

    rowsum(df, rep(seq_len(ceiling(nrow(df) / 5)), each = 5)[seq_len(nrow(df))]) / 10
    #  X61253 X61613 X66198
    #1  139.4   69.7   69.7
    #2 1219.0   69.7   69.7
    #3 2845.9  421.7  421.7
    #4 1866.5  580.6  544.3
    

    【讨论】:

    • 喜欢受 Plafort 启发的单线解决方案。数据的进一步清洁 - 某些列数据比其他列数据短,这就是为什么当我在 emply 单元格中运行此代码时,那些行中没有数据 Err:511 出现。有什么办法可以摆脱它,而且我仍然会得到索引列以及我的结果?我不想要。请帮忙。
    • @Knight:你能发布重现问题的示例数据吗?我不确定我是否理解发生了什么
    【解决方案3】:

    这是一个基本的 R 解决方案:

    index <- seq(5,nrow(df), by=5)
    splitup <- function(vec) {
      s <- split(vec,cumsum(tabulate(index+1, length(vec)))); 
      lapply(s, function(v) sum(v)/10)
    }
    
    sapply(df, splitup)
      X61253 X61613 X66198
    0 139.4  69.7   69.7  
    1 1219   69.7   69.7  
    2 2845.9 421.7  421.7 
    3 1866.5 580.6  544.3 
    

    感谢@akrun 不久前的想法。需要注意的一件事是您的示例有 18 行。对于您的数据,您是否需要忽略额外的行?

    备用

    这里有一个备用函数,可以显示已使用的间隔:

    index <- seq(5,nrow(df), by=5)
    splitup <- function(vec) {
      s <- split(vec, cut(seq_along(vec), c(-Inf, index, Inf))); 
      lapply(s, function(v) sum(v)/10)
    }
    sapply(df, splitup)
              X61253 X61613 X66198
    (-Inf,5]  139.4  69.7   69.7  
    (5,10]    1219   69.7   69.7  
    (10,15]   2845.9 421.7  421.7 
    (15, Inf] 1866.5 580.6  544.3 
    

    感谢@Ananda Mahto 的替代想法。

    数据

    df <- read.table(text="X61253 X61613 X66198
    279    140    140
    279    139    139
    278    139    139
    279    140    140
    279    139    139
    278    139    139
    3624   140    140
    279    139    139
    279    139    139
    7730   140    140
    278    139    139
    12180  139    139
    279   3660   3660
    279    140    140
    15443  139    139
    278    139    139
    18108 5527   5164
    279    140    140", header=T)
    

    【讨论】:

    • 任一解决方案都不起作用@platfort seq.default(5, nrow(df), by = 5) 中的错误:'to' 的长度必须为 1
    • 我刚刚再次复制并粘贴了数据,它仍然有效。您是在使用我回答中的数据先进行测试吗?
    • @Knight,如果您没有定义变量df,那么nrow(df) 将是NULL(因为df 是内置R 函数的名称)跨度>
    【解决方案4】:

    另一种方法:

    a <- as.matrix(DF)
    dim <- c(5, ceiling(nrow(a) / 5), ncol(a))
    #pad with NA
    a <- rbind(a, matrix(NA, ncol = ncol(a), nrow = 5 * dim[2] - nrow(a)))
    #turn into 5*4*3 array
    dim(a) <- dim
    
    res <- colSums(a, na.rm = TRUE) / 10
    colnames(res) <- names(DF)
    res
    #     X61253 X61613 X66198
    #[1,]  139.4   69.7   69.7
    #[2,] 1219.0   69.7   69.7
    #[3,] 2845.9  421.7  421.7
    #[4,] 1866.5  580.6  544.3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      相关资源
      最近更新 更多