как вычесть столбец из других столбцов в кадре данных - PullRequest
0 голосов
/ 08 января 2019

У меня есть фрейм данных, который состоит из 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

и т. Д.

Ответы [ 4 ]

0 голосов
/ 08 января 2019

Вам следует подумать об использовании 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)
)
0 голосов
/ 08 января 2019

Вот пользовательская функция: Вы можете добавить else, если вы хотите операторы.

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

Benchmark:

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

Результат:

 user  system elapsed 
   0.02    0.00    0.01 
0 голосов
/ 08 января 2019

Вы также можете сделать следующее без цикла:

# 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
0 голосов
/ 08 января 2019

Решил, просто выполнив

{
  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 - это фрейм данных. Может быть, это не самый хороший способ, но он добился цели

...