Подтвердить что ты не робот

Как добавить строку в фрейм данных с итоговыми значениями?

У меня есть кадр данных, где я хотел бы добавить дополнительную строку, которая суммирует значения для столбцов. Например, предположим, что у меня есть эти данные:

x <- data.frame(Language=c("C++", "Java", "Python"), 
                Files=c(4009, 210, 35), 
                LOC=c(15328,876, 200), 
                stringsAsFactors=FALSE)    

Данные выглядят следующим образом:

  Language Files   LOC
1      C++  4009 15328
2     Java   210   876
3   Python    35   200

Мой инстинкт должен сделать это:

y <- rbind(x, c("Total", colSums(x[,2:3])))

И это работает, он вычисляет итоговые значения:

> y
  Language Files   LOC
1      C++  4009 15328
2     Java   210   876
3   Python    35   200
4    Total  4254 16404

Проблема в том, что столбцы Files и LOC были преобразованы в строки:

> y$LOC
[1] "15328" "876"   "200"   "16404"

Я понимаю, что это происходит потому, что я создал вектор c("Total", colSums(x[,2:3]) со входами, которые являются как числами, так и строками, и преобразует все элементы в общий тип, так что все векторные элементы одинаковы. То же самое происходит с столбцами Files и LOC.

Какой лучший способ сделать это?

4b9b3361

Ответ 1

Вам нужен столбец языка в ваших данных, или более уместно подумать об этом столбце как row.names? Это изменит ваш data.frame из 4 наблюдений трех переменных в 4 наблюдения двух переменных (файлы и LOC).

x <- data.frame(Files=c(4009, 210, 35), LOC=c(15328,876, 200), row.names=c("C++", "Java", "Python"), stringsAsFactors=F)    
x["Total" ,] <- colSums(x)


> x
       Files   LOC
C++     4009 15328
Java     210   876
Python    35   200
Total   4254 16404

Ответ 2

Здесь вы получите то, что хотите, но может быть очень элегантное решение.

rbind(x, data.frame(Language="Total",t(colSums(x[,-1]))))

Для записи я предпочитаю ответ Chase, если вам не нужен столбец Language.

Ответ 3

Попробуйте это

y[4,] = c("Total", colSums(y[,2:3]))

Ответ 4

Если (1) нам не нужен заголовок "Language" в первом столбце, мы можем представить его с использованием имен строк, и если (2) нормально обозначить последнюю строку как "Sum", а не "Total" тогда мы можем использовать addmargins следующим образом:

rownames(x) <- x$Language
addmargins(as.table(as.matrix(x[-1])), 1)

даяние:

       Files   LOC
C++     4009 15328
Java     210   876
Python    35   200
Sum     4254 16404

Если нам нужен первый столбец с меткой "Language" и общая строка с меткой "Total", то его бит будет длиннее:

rownames(x) <- x$Language
Total <- sum
xa <- addmargins(as.table(as.matrix(x[-1])), 1, FUN = Total)
data.frame(Language = rownames(xa), as.matrix(xa[]), row.names = NULL)

даяние:

  Language Files   LOC
1      C++  4009 15328
2     Java   210   876
3   Python    35   200
4    Total  4254 16404

Ответ 5

Вы действительно хотите иметь итоговые значения столбцов в вашем кадре данных? Для меня интерпретация кадра данных теперь зависит от строки. Например,

  • Строки 1- (n-1): сколько файлов связано с конкретным языком
  • Строка n: сколько файлов связано с всеми языками

Это становится более запутанным, если вы начнете подмножать свои данные. Например, предположим, что вы хотите знать, какие языки имеют более 100 файлов:

> x = data.frame(Files=c(4009, 210, 35), 
                LOC=c(15328,876, 200), 
                row.names=c("C++", "Java", "Python"), 
                stringsAsFactors=FALSE)    
> x["Total" ,] = colSums(x)
> x[x$Files > 100,]
       Files   LOC
C++    4009 15328
Java    210   876
Total  4254 16404#But this refers to all languages!

Строка Total теперь неверна!

Лично я бы выработал суммы столбцов и сохранил их в отдельном векторе.

Ответ 6

Поскольку вы упоминаете, что это последний шаг перед экспортом для презентации, вы можете иметь имена столбцов, которые будут содержать пробелы в них для ясности (т.е. "Grand Total" ). Если это так, то следующее гарантирует, что созданный data.frame будет привязан к исходному набору данных без ошибки, вызванной несогласованными именами столбцов:

dfTotals <- data.frame(Language="Total",t(colSums(x[,-1]))))

colnames(dfTotals) <- names(x)  

rbind(x, dfTotals)

Ответ 7

Я думаю, что в настоящее время существует более простой способ с пакетом dplyr:

library(dplyr)
x <- mutate(x, Total = rowSums(x[, 2:3]))

Ответ 8

Ваш первоначальный инстинкт будет работать, если вы нажмете ваши столбцы на числовые:

y$LOC <- as.numeric(y$LOC)
y$Files <- as.numeric(y$Files)

Затем примените colSums() и rbind().

Ответ 9

Вы можете использовать заявку для каждой суммы col

Применить (df [-колонки, которые вам не нужны в сумме], 2, сумма)

И тогда вы можете

rbind

что данные в вашем df