Как добавить строку в фрейм данных с итоговыми значениями?
У меня есть кадр данных, где я хотел бы добавить дополнительную строку, которая суммирует значения для столбцов. Например, допустим, у меня есть эти данные:
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
Мой инстинкт должен сделать это:
- Понимание, когда data.table является ссылкой на (по сравнению с копией) другой data.table
- Передайте имя столбца data.frame в функцию
- Как добавить процентные или подсвеченные надписи над графиком процентного бара?
- Сопоставьте значения в кадре данных со значениями в другом кадре данных и замените прежний соответствующим шаблоном из другого кадра данных
- Получение участка с разбивкой по областям в R
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.
Что это лучший способ сделать это?
- Как указать / таблицу данных по номерам групп из group_by?
- dplyr - mutate: использовать имена динамических переменных
- выборки строк подгрупп из dataframe с dplyr
- Исключить группы, которые имеют разные значения
- Разделение столбца строки dataframe на несколько разных столбцов
- Ограничить оси ggplot2 без удаления данных (внешние ограничения): увеличить
- dplyr: Как использовать group_by внутри функции?
- Перекрывающиеся совпадения в R
См. adorn_totals()
из пакета adorn_totals()
:
library(janitor) x %>% adorn_totals("row") #> Language Files LOC #> C++ 4009 15328 #> Java 210 876 #> Python 35 200 #> Total 4254 16404
Числовые столбцы остаются в classе числовыми.
Отказ от ответственности: я создал этот пакет, включая adorn_totals()
который создан именно для этой задачи.
Вот способ, который дает вам то, что вы хотите, но может быть очень элегантное решение.
rbind(x, data.frame(Language="Total",t(colSums(x[,-1]))))
Для записи я предпочитаю ответ Чейз, если вам не нужен столбец Language
.
Вам нужен столбец «Язык» в ваших данных, или более уместно подумать об этом столбце как row.names
? Это изменит ваш data.frame из 4 наблюдений трех переменных в 4 наблюдения двух переменных (Files & 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
tidyverse
способом сделать это будет использование bind_rows
(или, в конечном итоге, add_rows
) и summarise
для вычисления сумм. Здесь проблема в том, что мы хотим суммы для всех, кроме одного, поэтому трюк будет:
summarise_all(x, funs(if(is.numeric(.)) sum(.) else "Total"))
В одной строке:
x %>% bind_rows(summarise_all(., funs(if(is.numeric(.)) sum(.) else "Total")))
Попробуй это
y[4,] = c("Total", colSums(y[,2:3]))
Если (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
Вы действительно хотите иметь итоговые значения столбцов в вашем кадре данных? Для меня интерпретация кадра данных теперь зависит от строки. Например,
- Строки 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
строка теперь не так!
Лично я бы выработал суммы столбцов и сохранил их в отдельном векторе.
Поскольку вы упоминаете, что это последний шаг перед экспортом для презентации, вы можете иметь имена столбцов, которые будут содержать пробелы в них для ясности (т. Е. «Grand Total»). Если это так, то следующее гарантирует, что созданный data.frame будет привязан к исходному набору данных без ошибки, вызванной несогласованными именами столбцов:
dfTotals <- data.frame(Language="Total",t(colSums(x[,-1])))) colnames(dfTotals) <- names(x) rbind(x, dfTotals)
Ваш первоначальный инстинкт будет работать, если вы зациклили свои столбцы на числовые:
y$LOC <- as.numeric(y$LOC) y$Files <- as.numeric(y$Files)
Затем примените colSums () и rbind ().
Вы можете использовать заявку на каждую сумму col
Применить (df [-колонки, которые вам не нужны в сумме], 2, сумма)
И тогда вы можете
rbind
эти данные в вашем df