【问题标题】:how to subtract a column to the other colums in a data frame如何将一列减去数据框中的其他列
【发布时间】:2019-01-08 19:12:01
【问题描述】:

我有一个包含 1000 行和 156 列的数据框。我试图将第一列减去接下来的 38 列,然后将第 39 列减去接下来的 38 列,依此类推,但我找不到办法。我只使用ncdf4,没有别的。像这样的

C1  C2  C3  C4  C5  C6  C7  C8
1   2   3   4   5   6   4   5
3   4   6   5   4   3   2   7

我希望它是

C1  C2  C3  C4  C5  C6  C7  C8
0   1   2   3   4   5   3   4
0   1   3   2   1   0  -1   4

逻辑是 前 38 列 - 第一列

第 39:77 栏 - 第 39 栏

等等。

【问题讨论】:

  • 这个减法背后的逻辑是什么?
  • 前 38 列 - 第一列然后第 39:77 列 - 第 39 列等等
  • 知道了!编辑您的问题以使其更清楚。
  • 为什么第二个块的范围不是39到76?

标签: r frame subtraction ncdf4


【解决方案1】:

简单地解决了它

{
  z[,1:38] <- z[,1:38]-z[,1]
  z[,39:77] <-z[,39:77]-z[,39]
  z[,78:118] <-z[,78:118]-z[,78]
  z[,119:156] <-z[,119:156]-z[,119]
}

其中 z 是数据框。可能不是最好的方法,但它成功了

【讨论】:

  • 检查我的答案,看看它是否有帮助。不过,for 循环通常不是最好的。
【解决方案2】:

您也可以在没有任何循环的情况下执行以下操作:

# sample data frame
df <- data.frame(matrix(data = seq(1,316),ncol = 158))

# split the data frame into list of data frame having columns
# 1 to 38, 39 to 77 and so on
df <- split.default(df, gl(round(ncol(df)/38),k = 38))

# subtract the last column from each
df <- do.call(cbind, lapply(df, function(f) f - f[,ncol(f)]))
colnames(df) <- paste0('C', seq(1,158))

print(head(df))

   C1  C2  C3  C4  C5
1 -74 -72 -70 -68 -66
2 -74 -72 -70 -68 -66

【讨论】:

    【解决方案3】:

    这是一个用户定义的函数:您可以根据需要添加 else if 语句。

    mydiff<-function(df){
      mydiff<-df
      for(i in 1:ncol(df)){
        if(i<=38){
          mydiff[,i]<-df[,i]-df[,1]
        }
        else if(i%in%c(39:77)){
          mydiff[,i]<-df[,i]-df[,39]
        }
    
        }
    
    mydiff 
    }
    
    mydiff(df1)
    

    输出:

     C1 C2 C3 C4 C5 C6 C7 C8
     0  1  2  3  4  5  3  4
     0  1  3  2  1  0 -1  4
    

    基准测试:

    system.time(result<-as.tibble(iris2) %>% 
                  select_if(is.numeric) %>% 
                  mydiff())
    

    结果:

     user  system elapsed 
       0.02    0.00    0.01 
    

    【讨论】:

      【解决方案4】:

      您应该考虑使用tidyverse 来解决这个问题,将包加载到 R 中对您的环境开销几乎没有影响,并且可以让您的生活更轻松。

       library(tidyverse)
      
      > df %>% 
         mutate_at(.vars = vars(num_range(prefix = 'C', 1:38)), .funs = function(x) x - .$C1) %>% 
         mutate_at(.vars = vars(num_range(prefix = 'C', 39:77)), .funs = function(x) x - .$C39)
      
        C1 C2 C3 C4 C38 C39 C40 C41 C42 C77
      1  0  1  2  3   4   0   1   2   3   4
      2  0  0  3  2   4   0   0   3   2   4
      

      数据

      df <-
      data.frame(
        C1 = c(1, 3),
        C2 = c(2, 3),
        C3 = c(3, 6),
        C4 = c(4, 5),
        C38 = c(5, 7),
        C39 = c(1, 3),
        C40 = c(2, 3),
        C41 = c(3, 6),
        C42 = c(4, 5),
        C77 = c(5, 7)
      )
      

      【讨论】:

        最近更新 更多