旋转需要更宽和更长的数据框

Abr*_*efa 3 pivot-table r dplyr

我正在处理一些政府来源的数据,其格式可以使用此代码复制:

Names <- c(rep("A",5),rep("B",5), rep("C",5))
Types <- c(rep(c("Income","Tax Paid","Consumption","Stimulus","NonDurable expenses"),3))
year1 <- c(rep(c(1000,100,300,100,200),3))
year2 <- c(rep(c(2000,200,600,200,400),3))
year3 <- c(rep(c(4000,400,800,400,800),3))
df <- data.frame(Names,Types,year1,year2,year3)
Run Code Online (Sandbox Code Playgroud)

我想要的是一个新的数据框

姓名 收入 消耗 刺激 非耐用型
A 第一年 1000 100 300 100 200
A 第二年 1000 100 300 100 200
A 第三年 1000 100 300 100 200
第一年 2000年 200 600 200 400
第二年 2000年 200 600 200 400
第三年 2000年 200 600 200 400

就这样继续下去。因此,对于每个人来说,将表格放在很长的位置year,并使用单元格名称作为Types具有相应值的新列。

我想到了一种处理这个问题的方法:按类型过滤掉每个类型,然后为每种类型设置单独的数据帧pivot_longer,然后是bind_cols结果。但我认为这是低效的。这是我的代码:

df %>% filter(Types == "Income") %>%
      pivot_longer(cols=c(year1:year3), names_to = "Year", values_to = "income") %>% select(-Types) %>%
  bind_cols(df %>% filter(Types == "Tax Paid") %>%
              pivot_longer(cols=c(year1:year3), names_to = "Year", values_to = "Tax_paid") %>% select(Tax_paid)) %>%
  bind_cols(df %>% filter(Types == "Consumption") %>%
              pivot_longer(cols=c(year1:year3), names_to = "Year", values_to = "Consumption") %>% select(Consumption)) %>%
  bind_cols(df %>% filter(Types == "Stimulus") %>%
              pivot_longer(cols=c(year1:year3), names_to = "Year", values_to = "Stimulus") %>% select(Stimulus)) %>%
  bind_cols(df %>% filter(Types == "NonDurable expenses") %>%
              pivot_longer(cols=c(year1:year3), names_to = "Year", values_to = "NonDurable_expenses") %>% select(NonDurable_expenses))
  
Run Code Online (Sandbox Code Playgroud)

有人可以帮助编写更好、更高效的代码吗?

Ben*_*ker 6

我认为这符合你的要求

library(tidyr); library(dplyr)
(df
    |> pivot_longer(year1:year3, names_to = "year") 
    |> pivot_wider(names_from = Types)
    |> rename_with(~ stringr::str_remove(., " +.*"))
)
Run Code Online (Sandbox Code Playgroud)

(整个表达式周围的额外括号是我的一种奇怪的格式/风格偏好;这样做允许每行以管道开头,而不是必须确保它们以管道结尾......)

  • 额外的括号有什么特殊原因吗? (3认同)