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

Я много смотрел на переполнение стека, но не смог найти ничего полезного для желаемого результата.

Для иллюстрации рассмотрим следующий пример фрейма данных:

      D     X     Y     Z     A     B     C    Total
 1   abc    2     3     4     7     2     1      19

Сумма соответствует сумме каждой строки.Для простоты, пусть B = 19, который является общим.Вывод, который я хочу получить:

    D     X     Y     Z     A     B     C    Total
 1  abc   1     2     3     4     5     2      B
 2  N/A   1/B   2/B   3/B   4/B   5/B   2/B    1

Здесь каждый элемент в 1-й строке делится на общее число, и это отражается во 2-й строке.Чтобы создать столбец для итога, я использовал mutate и сделал следующее:

df <- df %>% mutate(Total = X + Y + Z + A + B + C)

Но я не смог понять, как создать строку, в которой каждый элемент делится на общее число.

Любая помощь будет принята с благодарностью!Я не возражаю против использования mutate или data.table при этом, так как я использовал data.table для создания большого фрейма данных.

EDIT1: Мне очень жаль, что я не упомянул об этом, но столбец содержит некоторыестроки.Я отредактировал выше, чтобы отразить это.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Вот ответ dplyr на ваш вопрос.То, что вы действительно хотите сделать, может быть более сложным, но эти простые bind_rows, filter и mutate_all работают для простого предоставленного примера.

library(dplyr)
df <- data.frame(x = 2:3, y = 3:4, z = letters[1:2], total = c(0, 19))
bind_rows(
    df,
    filter(df, row_number() == n()) %>%
        mutate_if(is.numeric, funs(. / total))
)

# x         y z total
# 1 2.0000000 3.0000000 a     0
# 2 3.0000000 4.0000000 b    19
# 3 0.1578947 0.2105263 b     1
0 голосов
/ 12 октября 2018

Я добавил еще одну строку, чтобы сделать решение более общим.

В базе R мы можем разделить фрейм данных на столбец Total в этой строке, а затем rbind с исходным фреймом данных.

new_df <- rbind(df, df/df[, "Total"])
new_df

#           X         Y         Z         A         B          C Total
#1  2.0000000 3.0000000 4.0000000 7.0000000 2.0000000 1.00000000    19
#2  1.0000000 2.0000000 5.0000000 6.0000000 7.0000000 4.00000000    25
#11 0.1052632 0.1578947 0.2105263 0.3684211 0.1052632 0.05263158     1
#21 0.0400000 0.0800000 0.2000000 0.2400000 0.2800000 0.16000000     1

Если порядок важен и выесли вы хотите сохранить его, тогда мы можем просто изменить его порядок

rbind(new_df[c(T, F),], new_df[c(F, T),])

#           X         Y         Z         A         B          C Total
#1  2.0000000 3.0000000 4.0000000 7.0000000 2.0000000 1.00000000    19
#11 0.1052632 0.1578947 0.2105263 0.3684211 0.1052632 0.05263158     1
#2  1.0000000 2.0000000 5.0000000 6.0000000 7.0000000 4.00000000    25
#21 0.0400000 0.0800000 0.2000000 0.2400000 0.2800000 0.16000000     1

РЕДАКТИРОВАТЬ

Если есть определенные столбцы, которые являются строками, мы можем их игнорировать и использоватьbind_rows вместо rbind, поскольку он напрямую возвращает NA для несоответствующих столбцов.

library(dplyr)
bind_rows(df1, df1[!names(df1) %in% "D"]/df1[, "Total"])

#         X         Y         Z         A         B          C  Total    D
#1 2.0000000 3.0000000 4.0000000 7.0000000 2.0000000 1.00000000    19  abc
#2 1.0000000 2.0000000 5.0000000 6.0000000 7.0000000 4.00000000    25  def
#3 0.1052632 0.1578947 0.2105263 0.3684211 0.1052632 0.05263158     1 <NA>
#4 0.0400000 0.0800000 0.2000000 0.2400000 0.2800000 0.16000000     1 <NA>

данные

df <- structure(list(X = c(2, 1), Y = c(3, 2), Z = c(4, 5), A = c(7, 
  6), B = c(2, 7), C = c(1, 4), Total = c(19, 25)), .Names = c("X", 
  "Y", "Z", "A", "B", "C", "Total"), row.names = c("1", "2"), class = "data.frame")

df1 <-structure(list(X = c(2, 1), Y = c(3, 2), Z = c(4, 5), A = c(7, 
6), B = c(2, 7), C = c(1, 4), Total = c(19, 25), D = c("abc", 
"def")), .Names = c("X", "Y", "Z", "A", "B", "C", "Total", "D"
 ), row.names = c("1", "2"), class = "data.frame")
...