Как добавить строку в фрейм данных с итоговыми значениями?
У меня есть кадр данных, где я хотел бы добавить дополнительную строку, которая суммирует значения для столбцов. Например, предположим, что у меня есть эти данные:
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.
Какой лучший способ сделать это?
Ответы
Ответ 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