Добавьте строку с вычислениями в R

#r #dataframe

#r #фрейм данных

Вопрос:

Это кажется очень простым вопросом, но я долго боролся с ним. Далее следует упрощенная версия. У меня есть следующий набор данных:

 a <- c('I' , 'E')
ja <- c(30 , 20)
fe <- c(50, 40)
ma <- c(35 , 22)

x <- data.frame(a, ja , fe , ma)
x
#>   a ja fe ma
#> 1 I 30 50 35
#> 2 E 20 40 22
 

Создано 2020-12-04 пакетом reprex (версия 0.3.0)

Я хочу добавить строку 3, чтобы иметь цифры строки I минус строка E для ja, fe и ma. Таким образом, строка 3 будет выглядеть следующим образом:

 a     ja   fe   ma
I_E   10   10   13
 

Там будет 12 столбцов, по одному на каждый месяц, поэтому в идеале я хотел бы иметь возможность ссылаться на них кратко, например, как (в этом примере) ja:ma или тому подобное. Спасибо за любую помощь!

Комментарии:

1. Попробуй это cbind(a = paste0(x[1:2,1], collapse = "_"), x[1,-1] - x[2,-1])

Ответ №1:

Работает ли это:

 library(dplyr)
library(stringr)
x %>% 
  bind_rows(x %>% summarise(a = str_c(a, lead(a), sep = '_')) %>% na.omit() %>% 
                bind_cols(x %>% summarise(across(2:4, ~ . - lead(.))) %>% na.omit()))
    a ja fe ma
1   I 30 50 35
2   E 20 40 22
3 I_E 10 10 13
 

Комментарии:

1. Большое спасибо, это отлично сработало для моего несколько более сложного реального случая. Я знаком с некоторым кодом, но не со всем. Есть ли ссылка на код, на который вы можете мне указать?

2. @David, спасибо, для справки, вы можете перейти по этим ссылкам: dplyr.tidyverse.org/reference/across.html и dplyr.tidyverse.org/reference/bind.html

Ответ №2:

Не делайте этого.

Фреймы данных не являются таблицами Excel.

Способ R заключается в том, чтобы каждая строка отображалась как месяц. Вы должны начать с 3 столбцов: month_name, I и E. Затем вы можете создать 4-й столбец, который равен I минус E.

 df <- data.frame(
    month_name = c("ja", "fe", "ma"),
    I = c(30, 50, 35),
    E = c(20, 40, 22)
)

df$E_E <- df$I - df$E
 

Ответ №3:

Мы также можем использовать data.table подходы

 library(data.table)   
rbind(setDT(x), x[, c(list(a = 'I_E'), 
      lapply(.SD, function(x) diff(rev(x)))), .SDcols = 2:4])
#     a ja fe ma
#1:   I 30 50 35
#2:   E 20 40 22
#3: I_E 10 10 13
 

Комментарии:

1. Спасибо! Я далеко не так хорошо знаком с data.table, как с пакетами tidyverse. Сообщение Картника решило мою насущную проблему, требующую времени, но я полон сил, чтобы лучше ознакомиться с data.table.

2. @David Спасибо. Было бы отличной инвестицией, если бы вы получили доступ к пакету data.table, поскольку это было бы более эффективно при работе с различными преобразованиями