【问题标题】:Easiest way to re-arrange data frame in R在 R 中重新排列数据框的最简单方法
【发布时间】:2017-05-01 04:47:26
【问题描述】:

在 R 中教授数据处理和组织的网站有一百万个以上,但鉴于我的问题,我不确定什么是最有效的/我知道如何在 python 中轻松做到这一点,但什么是等价的在R中做到这一点的简单方法?

比如说,我有一个如下所示的数据框:

ROI <- c("a_01","a_02","a_03","b_01","b_02","b_03")
summer_1 <- runif(6, min=0, max=1)
winter_1 <- runif(6, min=0, max=1)
summer_2 <- runif(6, min=0, max=1)
winter_2 <- runif(6, min=0, max=1)
summer_3 <- runif(6, min=0, max=1)
winter_3 <- runif(6, min=0, max=1)
summer_4 <- runif(6, min=0, max=1)
winter_4 <- runif(6, min=0, max=1)
df <- data.frame(ROI,summer_1,winter_1,summer_2,winter_2,summer_3,winter_3,summer_4,winter_4)

> head(df)

ROI   summer_1 winter_1 summer_2 winter_2 summer_3 winter_3 summer_4 winter_4
a_01  0.29930  0.65683  0.37349  0.88818  0.35568 0.95592 0.08095 0.07626
a_02  0.20637  0.91795  0.32142  0.81373  0.31344 0.92150 0.05090 0.04731
a_03  0.20925  0.92048  0.32336  0.155956 0.60364 0.155893 0.06320 0.05835
b_01  0.23676  0.108526 0.63557 0.92560  0.46017 0.76339 0.06265 0.05079

但我想重新排列列,使其看起来像这样:

ROI   no  season value
a     1   summer 81.33328 
a     2   summer 15.34663
...

等等

到目前为止,我有这个:

library(stringr)
df$new <- str_split_fixed(dat$ROI, "_", 2)

我还能如何最好地解决这个问题?

【问题讨论】:

  • 您的意思是“不”来自“投资回报率”列还是来自“季节”列的后缀
  • 好问题!它应该来自ROI

标签: r dataframe transform


【解决方案1】:

我们可以通过tidyverse 做到这一点

library(tidyverse)
#split the 'ROI' into two columns
res <- separate(df, ROI, into = c("ROI", 'no'), convert = TRUE) %>% 
          #reshape from wide to long format 
          gather(season, value, summer_1:winter_2) %>%
          #split the season column into two
          separate(season, into = c('season', 'n')) %>%
          #remove the columns that are not needed
          select(-n)

head(res)
#  ROI no season    value
#1   a  1 summer 29.25740
#2   a  2 summer 22.48911
#3   a  3 summer 70.42230
#4   b  1 summer 51.88971
#5   b  2 summer 66.26196
#6   b  3 summer 92.04438

或者另一种选择是用cSplit 拆分列,使用data.table 中的melt 将其转换为“长”格式

library(splitstackshape)
res2 <- setnames(melt(cSplit(df, "ROI", sep="_"), id.var = c("ROI_1", "ROI_2"), 
  variable.name = "season"), 1:2, c("ROI", "no"))[, season := sub("_\\d+", "", season)][]
head(res2)
#   ROI no season    value
#1:   a  1 summer 29.25740
#2:   a  2 summer 22.48911
#3:   a  3 summer 70.42230
#4:   b  1 summer 51.88971
#5:   b  2 summer 66.26196
#6:   b  3 summer 92.04438

数据

set.seed(24)
ROI <- c("a_01","a_02","a_03","b_01","b_02","b_03")
summer_1 <- runif(6, min=0, max=100)
winter_1 <- runif(6, min=0, max=100)
summer_2 <- runif(6, min=0, max=100)
winter_2 <- runif(6, min=0, max=100)
df <- data.frame(ROI,summer_1,winter_1,summer_2,winter_2)

【讨论】:

  • 好的,我得到的错误是Too many values at 7 locations: 9, 13, 14, 15, 16, 17, 19。实际上,我的数据框中的最后一列是winter_4,所以我将收集线更改为:gather(season, value, summer_1:winter_4) %&gt;%。我应该做点别的吗?
  • @JAG2024 你的 tidyr 版本是什么?我没有发现您展示的示例有任何错误。我正在使用tidyr_0.6.1
  • 我第一次下载tidyverse 是1.1.1
  • @JAG2024 也许,个别包版本和 tidyverse 版本存在冲突。
  • 我会下载你的版本再试一次。
猜你喜欢
  • 2013-07-03
  • 2012-10-01
  • 1970-01-01
  • 2021-03-21
  • 2011-05-04
  • 2021-08-14
  • 2014-06-23
  • 2015-06-26
相关资源
最近更新 更多