我有以下格式的数据集row data
:
Id Avg_bed_2017 staff_2014 staff_2015 staff_2016 staff_2017 outpatient_2013
1 460265 0.00000 NA NA NA NA NA
2 16121 13.66667 497 508.5 515 505
我的目标是将其重塑为以下格式:
Id category year value
1 Avg_bed 2017 460265
2 Avg_bed 2017 16121
3 staff 2014 13.667
4 ..... .... .....
为此,我定义了一个函数split.col.name(col)
,该函数使用列的每个名称作为输入并将其拆分为category
和year
,并以两个元素的列表形式返回。 / p>
然后我设计了一个函数split.col.row (rowdline)
,然后将row data
的一行作为输入并返回后者的一行。
然后,我尝试(1)在split.col.row (rowdline)
的行(257K行)上运行row data
,并且(2)在每行上应用apply()
函数。 (1)非常慢,并且(2)没有适当地绑定行(生成的矩阵仅限于输入数据的大小,而在这种情况下,输出将有更多的行)。也许有一种更有效的方法来进行此重塑?
答案 0 :(得分:2)
这是一个tidyverse
解决方案:
# make sample data
set.seed(1839)
dat <- data.frame(
id = 1:3,
avgbed_2017 = rnorm(3), # note: rename this column
staff_2014 = rnorm(3),
staff_2015 = rnorm(3),
outpatient_2013 = rnorm(3)
)
# gather and separate
library(dplyr)
library(tidyr)
dat %>%
gather("key", "value", -id) %>% # gathers everything but id
# if you wanna get rid of NA values, say na.rm = TRUE in gather
separate("key", c("category", "year"), sep = "_")
请注意,您必须将avg_bed_2017
重命名为avgbed_2017
才能起作用。如果我比较擅长使用正则表达式,则可以使sep
中的separate
为正则表达式,仅在第二次出现下划线时匹配 -也许其他人可以向我展示如何。为了解决这个问题,我只重命名了上面的列,以便唯一的下划线是我们要分割的下划线。
每个@ Dave2e:
set.seed(1839)
data.frame(
id = 1:3,
avg_bed_2017 = rnorm(3),
staff_2014 = rnorm(3),
staff_2015 = rnorm(3),
outpatient_2013 = rnorm(3)
) %>%
gather("key", "value", -id) %>%
separate("key", c("category", "year"), sep = "_(?=[0-9]{4})")