У меня есть это df:
df = data.frame(Meaning = c('Tax', 'Internet', 'Tax', 'Phone', 'Tax', 'Car'),
Code = c(4656, 6152, 4656, 6150, 4656, 6151),
Total = c(0.73, 4.4, 1.33, 8, 1.67, 10),
Tax = c(0.73, NA, 1.33, NA, 1.67, NA),
Subtotal = c(NA, 3.67, NA, 6.67, NA, 8.33),
stringsAsFactors = FALSE)
> df
Meaning Code Total Tax Subtotal
Tax 4656 0.73 0.73 NA
Internet 6152 4.40 NA 3.67
Tax 4656 1.33 1.33 NA
Phone 6150 8.00 NA 6.67
Tax 4656 1.67 1.67 NA
Car 6151 10.00 NA 8.33
И я хотел бы использовать reshape() или stack, чтобы получить еще один data.frame, выглядящий так:
Code Meaning Category Price
6152 Internet Total 4.4
6152 Internet Subtotal 3.67
4656 Tax Subtotal 0.73
6150 Phone Total 8
6150 Phone Subtotal 6.67
4656 Tax Subtotal 1.33
6151 Car Total 10
6151 Car Subtotal 8.33
4656 Tax Subtotal 1.67
Где Category отображает столбец из df (Total или Subtotal), а Price отображается следующим образом: Total, Subtotal, Tax показано на df.
До сих пор я пытался с:
cbind(df[1:2], stack(lapply(df[-c(1:2)], as.character)))
Но он извлекает:
Meaning Code values ind
Tax 4656 0.73 Total
Internet 6152 4.4 Total
Tax 4656 1.33 Total
Phone 6150 8 Total
Tax 4656 1.67 Total
Car 6151 10 Total
Tax 4656 0.73 Tax
Internet 6152 <NA> Tax
Tax 4656 1.33 Tax
Phone 6150 <NA> Tax
Tax 4656 1.67 Tax
Car 6151 <NA> Tax
Tax 4656 <NA> Subtotal
Internet 6152 3.67 Subtotal
Tax 4656 <NA> Subtotal
Phone 6150 6.67 Subtotal
Tax 4656 <NA> Subtotal
Car 6151 8.33 Subtotal
Любые идеи?
ПРИМЕЧАНИЕ: Я пробовал со всеми этими ответами, но из-за того, что у меня df есть некоторые NA решения не работают.
Ответ 1, Ответ 2, Ответ 3
Возможно, проблема в том, что вам нужно просто отфильтровать строки NA.





Это выглядит правильно?
library(tidyverse)
df %>%
gather(Total, Tax, Subtotal, key = "key", value = "value") %>%
arrange(Code)
Meaning Code key value
1 Tax 4656 Total 0.73
2 Tax 4656 Total 1.33
3 Tax 4656 Total 1.67
4 Tax 4656 Tax 0.73
5 Tax 4656 Tax 1.33
6 Tax 4656 Tax 1.67
7 Tax 4656 Subtotal NA
8 Tax 4656 Subtotal NA
9 Tax 4656 Subtotal NA
10 Phone 6150 Total 8.00
11 Phone 6150 Tax NA
12 Phone 6150 Subtotal 6.67
13 Car 6151 Total 10.00
14 Car 6151 Tax NA
15 Car 6151 Subtotal 8.33
16 Internet 6152 Total 4.40
17 Internet 6152 Tax NA
18 Internet 6152 Subtotal 3.67
Я предпочитаю использовать функцию melt из data.table:
library(data.table)
melt(df,
id.vars = c('Meaning', 'Code'),
variable.name = 'Category',
value.name = 'Price')
Meaning Code Category price
1 Tax 4656 Total 0.73
2 Internet 6152 Total 4.40
3 Tax 4656 Total 1.33
4 Phone 6150 Total 8.00
5 Tax 4656 Total 1.67
6 Car 6151 Total 10.00
7 Tax 4656 Tax 0.73
8 Internet 6152 Tax NA
9 Tax 4656 Tax 1.33
10 Phone 6150 Tax NA
11 Tax 4656 Tax 1.67
12 Car 6151 Tax NA
13 Tax 4656 Subtotal NA
14 Internet 6152 Subtotal 3.67
15 Tax 4656 Subtotal NA
16 Phone 6150 Subtotal 6.67
17 Tax 4656 Subtotal NA
18 Car 6151 Subtotal 8.33
Почему бы не использовать новый пакет tidyverse
tidyr. Вот шпаргалка: ссылка на сайт. Используйте «Памятку по импорту данных», с. 2. Вам нужны функцииspreadиgather.