2013-09-03 11 views
2

У меня есть R dataframe в следующем виде:Создание новых переменных в R data.frame суммированием на основе факторов

FIRM WORKER HOURS 
FIRM1 A1  H1 
FIRM1 A2  H2 
FIRM1 A3  H3 
FIRM1 B1  H4 
FIRM1 B2  H5 
FIRM2 A1  H6 
FIRM2 C1  H7 

Есть фирмы, которые имеют работников по различным категориям образования (A, B, C, ...). Я хочу преобразовать dataframe так, чтобы категории образования суммировались с собственным столбцом, и все фирмы имели бы только одну строку для каждого. Поэтому мне нужно, чтобы преобразовать исходную dataframe в следующем вид:

FIRM HOURS_A HOURS_B HOURS_C 
FIRM1 H1+H2+H3 H4+H5 
FIRM2 H6    H7 

Что бы опрятный способ сделать это?

ответ

2

Первый агрегат, а затем изменить форму:

данных:

x <- read.table(header=TRUE, text=" 
FIRM WORKER HOURS 
FIRM1 A1  1 
FIRM1 A2  2 
FIRM1 A3  3 
FIRM1 B1  4 
FIRM1 B2  5 
FIRM2 A1  6 
FIRM2 C1  7 
") 

Код:

tmp <- aggregate(HOURS~FIRM+WORK, data=within(x, WORK <- substr(WORKER,1,1)), sum) 

reshape(tmp, idvar="FIRM", timevar="WORK", direction="wide") 

Результат:

FIRM HOURS.A HOURS.B HOURS.C 
1 FIRM1  6  9  NA 
2 FIRM2  6  NA  7 
+0

Удивительно! Он работает красиво. Огромное спасибо! – Antti

0

Я предполагаю, что вы имеете в виду вы действительно хотите суммировать определенное значение s и что ваш data.frame выглядит примерно так:

mydf <- structure(
    list(FIRM = c("FIRM1", "FIRM1", "FIRM1", "FIRM1", "FIRM1", "FIRM2", "FIRM2"), 
     WORKER = c("A", "A", "A", "B", "B", "A", "C"), 
     HOURS = c(10L, 20L, 15L, 13L, 12L, 9L, 16L)), 
    .Names = c("FIRM", "WORKER", "HOURS"), 
    class = "data.frame", row.names = c(NA, -7L)) 
mydf 
# FIRM WORKER HOURS 
# 1 FIRM1  A 10 
# 2 FIRM1  A 20 
# 3 FIRM1  A 15 
# 4 FIRM1  B 13 
# 5 FIRM1  B 12 
# 6 FIRM2  A  9 
# 7 FIRM2  C 16 

Затем вы можете использовать xtabs:

xtabs(HOURS ~ FIRM + WORKER, mydf) 
#  WORKER 
# FIRM  A B C 
# FIRM1 45 25 0 
# FIRM2 9 0 16 

Или, вы можете melt ваш набор данных и изменить его с dcast:

library(reshape2) 
dfL <- melt(mydf, id.vars=c("FIRM", "WORKER")) 
dcast(dfL, FIRM ~ variable + WORKER, fun.aggregate=sum, value.var="value") 
# FIRM HOURS_A HOURS_B HOURS_C 
# 1 FIRM1  45  25  0 
# 2 FIRM2  9  0  16 
Смежные вопросы