R сумма строк для разных групп столбцов, которые начинаются с аналогичной строки
Я совершенно новичок в R, и это первый раз, когда я осмеливаюсь задать вопрос здесь.
Я работаю с набором данных с масштабами likert, и я хочу, чтобы сумма строк по другой группе столбцов, которые разделяют первые строки в их имени.
df <- as.data.frame(rbind(rep(sample(1:5),4),rep(sample(1:5),4)))
var.names <- c("emp_1","emp_2","emp_3","emp_4","sat_1","sat_2"
,"sat_3","res_1","res_2","res_3","res_4","com_1",
"com_2","com_3","com_4","com_5","cap_1","cap_2",
"cap_3","cap_4")
names(df) <- var.names
Итак, что я сделал, было используйте функцию grep, чтобы суммировать строки указанных переменных, которые начинались с определенных строк, и хранить их в новой переменной. Но я должен написать новую строку кода для каждой переменной.
df$emp_t <- rowSums(df[, grep("bemp.", names(df))])
df$sat_t <- rowSums(df[, grep("bsat.", names(df))])
df$res_t <- rowSums(df[, grep("bres.", names(df))])
df$com_t <- rowSums(df[, grep("bcom.", names(df))])
df$cap_t <- rowSums(df[, grep("bcap.", names(df))])
но в наборе данных гораздо больше переменных, и я хотел бы знать, есть ли способ сделать это только с одной строкой кода. Например, можно каким-то образом сгруппировать переменные, начинающиеся с одних и тех же строк, а затем применить строку функция.
спасибо заранее!
3 ответов
одним из возможных решений является транспонирование df
и вычислить суммы для правильных столбцов, используя базу R
согласитесь с MrFlick, что вы можете поместить свои данные в длинный формат (см. reshape2
, tidyr
), но чтобы ответить на ваш вопрос:
cbind(
df,
sapply(split.default(df, sub("_.*$", "_t", names(df))), rowSums)
)
сделает трюк
вам будет лучше в долгосрочной перспективе, если вы поместите свои данные в опрятный вид. Проблема в том, что данные имеют широкий, а не длинный формат. И имена переменных, например, emp_1
, на самом деле две отдельные части данных: класс человека и идентификационный номер человека (или что-то в этом роде). Вот решение вашей проблемы с dplyr и tidyr.
library(dplyr)
library(tidyr)
df %>%
gather(key, value) %>%
extract(key, c("class", "id"), "([[:alnum:]]+)_([[:alnum:]]+)") %>%
group_by(class) %>%
summarize(class_sum = sum(value))
Сначала мы преобразуем фрейм данных из широкого в длинный формат с gather()
. Тогда мы разделить значения emp_1
в отдельных столбцах class
и id
С extract()
. Наконец, мы группируем по классу и суммируем значения в каждом классе. Результат:
Source: local data frame [5 x 2]
class class_sum
1 cap 26
2 com 30
3 emp 23
4 res 22
5 sat 19