当我在数据框中创建转换变量时(例如,现有变量的标准化版本),如果它们以这种方式放在它们的“父”变量旁边通常会很方便(例如,varname1,varname1_z,varname2,varname2_z,等等。)。但是新变量的默认位置是在数据帧的末尾。
有没有办法有效地将新创建的变量与其“父”变量放在一起,以便更好地组织数据?
我目前可以使用select()和名为moveme()的自定义函数更改数据框中的变量位置,但我正在尝试使此变量放置过程更加自动化,以便在创建变量时放置变量。
在下面的代码示例中,您将在数据帧的末尾看到我新创建的所有“_z”变量。有没有办法让我们能够以自动化的方式将它们与未标准化的父母放在一起?
感谢您的支持。
library(tidyverse)
mpg %>%
mutate_if(is.numeric, funs(z = scale(.) %>% as.double()))
答案 0 :(得分:1)
一种方法是:
gather()
将您的数据转换为“长”格式,并根据需要进行分组gather()
再次将新旧数据列放在一列spread()
将数据转换为您喜欢的格式。以下是一个例子:
numeric_cols <- mpg %>% select_if(is.numeric) %>% names
mpg %>%
rownames_to_column %>%
mutate(rowname = rowname %>% as.numeric) %>%
gather(param, quantity, !! numeric_cols) %>%
group_by(param) %>%
mutate(z_score = scale(quantity)) %>%
gather(number_type, value, quantity:z_score) %>%
unite(new_col_name, param, number_type) %>%
spread(new_col_name, value)
这会导致数据框的head()
为
rowname manufacturer model trans drv fl class cty_quantity cty_z_score
1 1 audi a4 auto(l5) f p compact 18 0.2681016
2 2 audi a4 manual(m5) f p compact 21 0.9729978
3 3 audi a4 manual(m6) f p compact 20 0.7380324
4 4 audi a4 auto(av) f p compact 21 0.9729978
5 5 audi a4 auto(l5) f p compact 16 -0.2018293
6 6 audi a4 manual(m5) f p compact 18 0.2681016
cyl_quantity cyl_z_score displ_quantity displ_z_score hwy_quantity
1 4 -1.1721058 1.8 -1.2939999 29
2 4 -1.1721058 1.8 -1.2939999 29
3 4 -1.1721058 2.0 -1.1391962 31
4 4 -1.1721058 2.0 -1.1391962 30
5 6 0.0689474 2.8 -0.5199816 26
6 6 0.0689474 2.8 -0.5199816 26
hwy_z_score year_quantity year_z_score
1 0.9336964 1999 -0.997861
2 0.9336964 1999 -0.997861
3 1.2695687 2008 0.997861
4 1.1016326 2008 0.997861
5 0.4298879 1999 -0.997861
6 0.4298879 1999 -0.997861
我认为这有你想要的形式。几个笔记:
group_by
是必要的,这样就可以为每个参数创建z分数,而不是计算数据集中所有数字的无意义z分数unite(..., param, number_type)
而不是unite(..., number_type, param)
。后者将所有未转换的列组合在一起,然后是所有z-score列。rownames_to_column
行是必需的,因为否则起始数据帧的行不是唯一的,这在尝试找出如何重新构建宽数据时会出现spread()
个问题。