我有多个数据格式/标签,结构相同,但内容不同。他们的名字是我唯一能区分他们的方法。其目标是将它们合并为一个数据帧,其中包含一个因子列。原始的数据文件在每小时/度量中有一列,所以首先我想收集所有数据。
假设5到11列的mtcar df是我的小时列。
mt1 <- mtcars
mt2 <- mtcars
mt3 <- mtcars
mt4 <- mtcars
mtlist <- list(m1 = mt1,
m2 = mt2,
m3 = mt3,
m4 = mt4)
require(tidyverse)
mtlist_tidy <- lapply(mtlist, function(x){
df <- x %>%
gather(exp, temp_name, 5:11)
return(df)
})
现在我被困住了。我需要将mtlist_tidy中每个dfs中的“mtlist_tidy”列重命名为该df的名称,即m1、m2等:
> head(mtlist_tidy$m1)
mpg cyl disp hp exp temp_name
1 21.0 6 160 110 drat 3.90
2 21.0 6 160 110 drat 3.90
3 22.8 4 108 93 drat 3.85
4 21.4 6 258 110 drat 3.08
5 18.7 8 360 175 drat 3.15
6 18.1 6 225 105 drat 2.76
应该变成
> head(mtlist_tidy$m1)
mpg cyl disp hp exp m1
1 21.0 6 160 110 drat 3.90
2 21.0 6 160 110 drat 3.90
3 22.8 4 108 93 drat 3.85
4 21.4 6 258 110 drat 3.08
5 18.7 8 360 175 drat 3.15
6 18.1 6 225 105 drat 2.76
然后purrr::reduce(mtlist_tidy, full_join)
就会工作,完成我的任务。
我想必须有一个只使用purrr
并跳过lapply的解决方案,但我对这个包还不太熟悉。
发布于 2017-07-28 16:10:25
有几个想法:
首先,要解决当前的问题,可以使用map2
同时遍历列表和列表的名称。然后,您可以通过gather_
(用于标准评估)在列表名称中命名新列。
map2(mtlist, names(mtlist), ~gather_(.x, "exp", .y, names(.x)[5:11]) )
注意,下一个版本的purrr将imap
作为循环遍历列表和列表名称的捷径。另外,下一个版本的tidyr将使用tidyeval
,gather_
将被废弃。
其次,您可以通过使用map_df
来循环而不是使用lapply
来保持长格式。map_df
在幕后使用bind_rows
,您可以通过.id
参数为每个列表包含一个分组变量。
mtlist %>%
map_df(~.x %>% gather("exp", "temp_name", 5:11), .id = "name" )
要将数据集设置为宽格式,可以使用spread
。在本例中,它需要做更多的工作,因为一些标识变量(如hp
和disp
)在多个行中具有相同的值。
mtlist %>%
map_df(~.x %>% gather("exp", "temp_name", 5:11), .id = "name" ) %>%
group_by(name) %>%
mutate( rows = 1:n() ) %>%
spread(name, temp_name)
发布于 2017-07-28 17:16:13
您可能需要添加一些NSE魔术:
library(rlang)
mtlist_tidy %>% map2(., names(.), ~rename(.x, UQ(sym(.y)) := temp_name))
发布于 2017-07-28 13:18:50
这样能行吗?
lapply(mtlist_tidy, function(i) {
names(i)["temp_name"] <- names(mtlist)[i] } )
https://stackoverflow.com/questions/45374422
复制相似问题