我无法重新排列以下数据框:
set.seed(45)
dat1 <- data.frame(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dat1
name numbers value
1 firstName 1 0.3407997
2 firstName 2 -0.7033403
3 firstName 3 -0.3795377
4 firstName 4 -0.7460474
5 secondName 1 -0.8981073
6 secondName 2 -0.3347941
7 secondName 3 -0.5013782
8 secondName 4 -0.1745357
Run Code Online (Sandbox Code Playgroud)
我想重塑它,以便每个唯一的"名称"变量是一个rowname,其中"值"作为沿该行的观察值,"数字"作为同名.有点像:
name 1 2 3 4
1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
Run Code Online (Sandbox Code Playgroud)
我看melt,并cast和其他一些东西,但没有人可以做的工作.
Cha*_*ase 240
使用reshape功能:
reshape(dat1, idvar = "name", timevar = "numbers", direction = "wide")
Run Code Online (Sandbox Code Playgroud)
Gre*_*gor 125
新的(2014年)tidyr包也做到这一点简单地说,与gather()/ spread()是的条款melt/ cast.
library(tidyr)
spread(dat1, key = numbers, value = value)
Run Code Online (Sandbox Code Playgroud)
来自github,
spread是一个重新gather设计,旨在配合整洁的数据框架,并与数据分析建立一个坚实的管道,pivot_wider并pivot_longer建立一个坚实的管道.就像
spread/gather重塑tidyr不到一样,做得不到reshape2.它专门用于整理数据,而不是一般的重塑magrittr,或重塑的一般聚合.特别是,内置方法仅适用于数据帧,并且不dplyr提供边距或聚合.
Ist*_*sta 69
您可以使用该reshape()函数或reshape包中的melt()/ cast()functions 执行此操作.对于第二个选项,示例代码是
library(reshape)
cast(dat1, name ~ numbers)
Run Code Online (Sandbox Code Playgroud)
或使用 reshape2
library(reshape2)
dcast(dat1, name ~ numbers)
Run Code Online (Sandbox Code Playgroud)
Sym*_*xAU 40
如果性能是一个问题的另一个选择是使用'的融合和dcast函数data.table的扩展reshape2
library(data.table)
setDT(dat1)
dcast(dat1, name ~ numbers, value.var = "value")
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
Run Code Online (Sandbox Code Playgroud)
而且,从data.table v1.9.6开始,我们可以在多列上进行转换
## add an extra column
dat1[, value2 := value * 2]
## cast multiple value columns
dcast(dat1, name ~ numbers, value.var = c("value", "value2"))
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
Run Code Online (Sandbox Code Playgroud)
akr*_*run 27
使用 devel 版本tidyr ‘0.8.3.9000’,有pivot_wider和pivot_longer被概括为从 1 列到多列进行整形(分别为长 -> 宽、宽 -> 长)。使用 OP 的数据
- 单列长 -> 宽
library(dplyr)
library(tidyr)
dat1 %>%
pivot_wider(names_from = numbers, values_from = value)
# A tibble: 2 x 5
# name `1` `2` `3` `4`
# <fct> <dbl> <dbl> <dbl> <dbl>
#1 firstName 0.341 -0.703 -0.380 -0.746
#2 secondName -0.898 -0.335 -0.501 -0.175
Run Code Online (Sandbox Code Playgroud)
-> 创建了另一列用于显示功能
dat1 %>%
mutate(value2 = value * 2) %>%
pivot_wider(names_from = numbers, values_from = c("value", "value2"))
# A tibble: 2 x 9
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 firstName 0.341 -0.703 -0.380 -0.746 0.682 -1.41 -0.759 -1.49
#2 secondName -0.898 -0.335 -0.501 -0.175 -1.80 -0.670 -1.00 -0.349
Run Code Online (Sandbox Code Playgroud)
Jim*_* M. 26
使用您的示例数据框,我们可以:
xtabs(value ~ name + numbers, data = dat1)
Run Code Online (Sandbox Code Playgroud)
mpa*_*nco 18
其他两个选择:
基础包:
df <- unstack(dat1, form = value ~ numbers)
rownames(df) <- unique(dat1$name)
df
Run Code Online (Sandbox Code Playgroud)
sqldf 包:
library(sqldf)
sqldf('SELECT name,
MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1,
MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2,
MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3,
MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4
FROM dat1
GROUP BY name')
Run Code Online (Sandbox Code Playgroud)
Ron*_*hah 11
使用基R aggregate功能:
aggregate(value ~ name, dat1, I)
# name value.1 value.2 value.3 value.4
#1 firstName 0.4145 -0.4747 0.0659 -0.5024
#2 secondName -0.8259 0.1669 -0.8962 0.1681
Run Code Online (Sandbox Code Playgroud)
小智 7
更简单的方法!
devtools::install_github("yikeshu0611/onetree") #install onetree package
library(onetree)
widedata=reshape_toWide(data = dat1,id = "name",j = "numbers",value.var.prefix = "value")
widedata
name value1 value2 value3 value4
firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
Run Code Online (Sandbox Code Playgroud)
如果你想从宽变回长,只需将宽变回长,而不会改变对象。
reshape_toLong(data = widedata,id = "name",j = "numbers",value.var.prefix = "value")
name numbers value
firstName 1 0.3407997
secondName 1 -0.8981073
firstName 2 -0.7033403
secondName 2 -0.3347941
firstName 3 -0.3795377
secondName 3 -0.5013782
firstName 4 -0.7460474
secondName 4 -0.1745357
Run Code Online (Sandbox Code Playgroud)
有从赢矢量天才科学家的数据(即发人非常强大的新包装vtreat,seplyr并replyr调用)cdata.它实现了本文档和本博文中描述的"协调数据"原则.我们的想法是,无论您如何组织数据,都应该可以使用"数据坐标"系统识别各个数据点.以下摘录自John Mount最近的博客文章:
整个系统基于两个原语或运算符cdata :: moveValuesToRowsD()和cdata :: moveValuesToColumnsD().这些操作符具有pivot,un-pivot,one-hot编码,转置,移动多行和多列以及许多其他变换作为简单的特殊情况.
根据cdata原语很容易编写许多不同的操作.这些运算符可以在内存或大数据规模(使用数据库和Apache Spark;对于大数据使用cdata :: moveValuesToRowsN()和cdata :: moveValuesToColumnsN()变体).变换由控制表控制,控制表本身是变换的图(或图片).
我们将首先构建控制表(有关详细信息,请参阅博客文章),然后执行从行到列的数据移动.
library(cdata)
# first build the control table
pivotControlTable <- buildPivotControlTableD(table = dat1, # reference to dataset
columnToTakeKeysFrom = 'numbers', # this will become column headers
columnToTakeValuesFrom = 'value', # this contains data
sep="_") # optional for making column names
# perform the move of data to columns
dat_wide <- moveValuesToColumnsD(tallTable = dat1, # reference to dataset
keyColumns = c('name'), # this(these) column(s) should stay untouched
controlTable = pivotControlTable# control table above
)
dat_wide
#> name numbers_1 numbers_2 numbers_3 numbers_4
#> 1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
#> 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
Run Code Online (Sandbox Code Playgroud)
基地 reshape功能可以正常工作:
df <- data.frame(
year = c(rep(2000, 12), rep(2001, 12)),
month = rep(1:12, 2),
values = rnorm(24)
)
df_wide <- reshape(df, idvar="year", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
Run Code Online (Sandbox Code Playgroud)
哪里
idvar 是分隔行的类的列timevar 是要广泛应用的课程列v.names 是包含数值的列direction 指定宽或长格式sep参数是在timevar类名之间和v.names输出中使用的分隔符data.frame。如果不idvar存在,请在使用reshape()函数之前创建一个:
df$id <- c(rep("year1", 12), rep("year2", 12))
df_wide <- reshape(df, idvar="id", timevar="month", v.names="values", direction="wide", sep="_")
df_wide
Run Code Online (Sandbox Code Playgroud)
请记住,这idvar是必需的!在timevar与v.names部分很容易。该函数的输出比其他一些函数更可预测,因为所有内容都已明确定义。