Dcast только одна переменная в новый столбец R

Я пытаюсь dcast мои данные, чтобы я мог выделить только Actual значения в новый столбец. Тем не менее, единственный способ, которым мне удалось это сделать, это dcast а потом melt назад. Мне было интересно, есть ли более эффективное решение.

Шаг 1:

Я немного подготовился к своим данным, но это выглядит так:

> test_m <- melt(test, id.vars = c("category", "Budget_year", "State"))
> test_m <- test_m[,c("Year", "Type_of_observation"):= tstrsplit(variable, " ", fixed = TRUE)]
> test_m[,variable := NULL]
> head(test_m, n = 10)

          category Budget_year State value    Year Type_of_observation
 1:  Transfer Duty     2000_01     N  1916 1998-99              Actual
 2:       Land Tax     2000_01     N   948 1998-99              Actual
 3:    Payroll Tax     2000_01     N  3605 1998-99              Actual
 4: Total Gambling     2000_01     N  1419 1998-99              Actual
 5:            GST     2000_01     N  4705 1998-99              Actual
 6:  Transfer Duty     2000_01     N  1747 1999-00              Budget
 7:       Land Tax     2000_01     N   830 1999-00              Budget
 8:    Payroll Tax     2000_01     N  3616 1999-00              Budget
 9: Total Gambling     2000_01     N  1558 1999-00              Budget
10:            GST     2000_01     N  5162 1999-00              Budget

Теперь я хочу сделать новую колонку из Type_of_observation колонка, но только принимая Actual наблюдения и оставляя все другие виды наблюдений позади. Мой текущий метод заключается в dcast а потом melt, следующее:

Шаг 2: желаемый результат

> test_c <- dcast(test_m, category + Budget_year + State + Year ~ Type_of_observation)
> test_mc <- melt(test_c, id.vars = c("category", "Budget_year", "State", "Year", "Actual"), measure.vars = c("Budget", "Estimate", "Revised"))
> head(test_mc, n = 10)
    category Budget_year State    Year Actual variable value
 1:      GST     2000_01     N 1998-99   4705   Budget    NA
 2:      GST     2000_01     N 1999-00     NA   Budget  5162
 3:      GST     2000_01     N 2000-01     NA   Budget  8318
 4:      GST     2000_01     N 2001-02     NA   Budget    NA
 5:      GST     2000_01     N 2002-03     NA   Budget    NA
 6:      GST     2000_01     N 2003-04     NA   Budget    NA
 7: Land Tax     2000_01     N 1998-99    948   Budget    NA
 8: Land Tax     2000_01     N 1999-00     NA   Budget   830
 9: Land Tax     2000_01     N 2000-01     NA   Budget   921
10: Land Tax     2000_01     N 2001-02     NA   Budget    NA

Так что теперь у меня есть колонка для Actuals и все остальные виды наблюдений оставлены в variable колонка.

Есть ли способ, которым я могу пойти с test_m в test_mc без необходимости делать оба dcast а также melt? Я предпочтительно после data.table решение, но я открыт для всего.

Вот dput за test_m:

> dput(test_m)
structure(list(category = c("Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST", "Transfer Duty", "Land Tax", "Payroll Tax", 
"Total Gambling", "GST"), Budget_year = c("2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01", "2000_01", "2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01", "2000_01", "2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01", "2000_01", "2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01", "2000_01", "2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01", "2000_01", "2000_01", "2000_01", 
"2000_01", "2000_01", "2000_01"), State = c("N", "N", "N", "N", 
"N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", 
"N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", 
"N", "N", "N", "N", "N"), value = c("1916", "948", "3605", "1419", 
"4705", "1747", "830", "3616", "1558", "5162", "2249", "889", 
"3742", "1578", "5173", "1746", "921", "3931", "1212", "8318", 
"1686", "948", "4146", "1241", "9520", "1756", "971", "4258", 
"1309", "9789", "1904", "991", "4503", "1374", "10006"), Year = c("1998-99", 
"1998-99", "1998-99", "1998-99", "1998-99", "1999-00", "1999-00", 
"1999-00", "1999-00", "1999-00", "1999-00", "1999-00", "1999-00", 
"1999-00", "1999-00", "2000-01", "2000-01", "2000-01", "2000-01", 
"2000-01", "2001-02", "2001-02", "2001-02", "2001-02", "2001-02", 
"2002-03", "2002-03", "2002-03", "2002-03", "2002-03", "2003-04", 
"2003-04", "2003-04", "2003-04", "2003-04"), Type_of_observation = c("Actual", 
"Actual", "Actual", "Actual", "Actual", "Budget", "Budget", "Budget", 
"Budget", "Budget", "Revised", "Revised", "Revised", "Revised", 
"Revised", "Budget", "Budget", "Budget", "Budget", "Budget", 
"Estimate", "Estimate", "Estimate", "Estimate", "Estimate", "Estimate", 
"Estimate", "Estimate", "Estimate", "Estimate", "Estimate", "Estimate", 
"Estimate", "Estimate", "Estimate")), .Names = c("category", 
"Budget_year", "State", "value", "Year", "Type_of_observation"
), row.names = c(NA, -35L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x026c24a0>)

2 ответа

Вы можете сначала завершить дела, а затем присоединиться к своему набору данных.

Наконец, вы обновляете соединение для поиска фактических значений.

#create complete cases
ans <- test_m[CJ(category=category, Budget_year=Budget_year, State=State, Year=Year, Type_of_observation=c("Budget", "Estimate", "Revised"), unique=TRUE),
    on=.(category, Budget_year, State, Year, Type_of_observation)][
        #update join
        test_m[Type_of_observation=="Actual"], 
        Actual := i.value,
        on=.(category, Budget_year, State, Year)]

#order to match test_mc
setorder(ans, category, Budget_year, State, Year, Type_of_observation)[]

Я думаю, что у меня есть прямой data.table метод для достижения этой цели, используя setkey и присоединяясь в скобках.

Я буду использовать более простой data.table, Цель состоит в том, чтобы получить interest_rate в свою колонку.

samp <- data.table(
  group=c("a","a","a","b","b","b","c","c","c"),
  variable=c("balance", "end_balance","interest_rate"),
  value=c(1000, 940, .05, 1200, 1040, .08, 980, 970, .10)
)


setkey(samp, group)

#  This will create a data.table with just our desired variable value, interest_rate, by group
samp[variable=="interest_rate", .(interest_rate=unique(value)), by=.(group)]

#  We then join this to the original data.table using the already set key and
#  drop the interest_rate rows in the final data.table
samp[samp[variable=="interest_rate", .(interest_rate=unique(value)), by=.(group)]][variable!="interest_rate"]
Другие вопросы по тегам