从宽格式到长格式,结果在多列中
from wide format to long format with results in multiple columns
我有一个类似于以下数据框的数据,但每个组合都有大约十个字段,从 name1、adress1、city1 等开始
id name1 adress1 name2 adress2 name3 adress3
1 1 John street a Burt street d chris street 1
2 2 Jack street b Ben street e connor street 2
3 3 Joey <NA> Bob street f <NA> <NA>
现在我想重新排列这些数据,使其更有用,看起来应该是这样的,但包含它来自哪个条目的信息:
id origin names adresses
1 1 1 John street a
2 2 1 Jack street b
3 3 1 Joey <NA>
4 1 2 Burt street d
5 2 2 Ben street e
6 3 2 Bob street f
7 1 3 chris street 1
8 2 3 connor street 2
使用 tidyr 我可以获得长格式,但我有一个包含所有变量名称的键列,name1、name2、name3、street1 等。
我也尝试过使用单独的数据框,每个组合一个,例如一个用于名称的数据框,一个用于街道等。但是将所有内容重新组合在一起会导致错误的记录,因为您只能在 id 上加入,并且在长格式中会复制此 ID。我也一直在研究 Reshape2,但这会导致同样的问题。
我见过的所有从宽到长的转换都是当你有一个列要转换成的时候。我正在寻找 10 列的最终结果,或者如示例中的 2 列。
是否有我忽略的功能?
#code to generete the dataframes:
df <- data.frame(id = c(1,2,3),
name1 = c("John", "Jack", "Joey"),
adress1 = c("street a", "street b", NA),
name2 = c("Burt", "Ben", "Bob"),
adress2 = c("street d", "street e", "street f"),
name3 = c("chris", "connor", NA),
adress3 = c("street 1", "street 2", NA),
stringsAsFactors = FALSE)
expecteddf <- data.frame(id = c(1,2,3,1,2,3,1,2),
origin = c(rep(1, 3), rep(2, 3), rep(3, 2)),
names = c("John", "Jack", "Joey", "Burt", "Ben", "Bob", "chris", "connor"),
adresses = c("street a", "street b", NA, "street d", "street e", "street f", "street 1", "street 2"),
stringsAsFactors = FALSE
)
我们可以使用 data.table 的 devel
版本中的 melt
,它可以为 measure
列使用多个 patterns
。安装'data.table'开发版的说明是here
我们将'data.frame'转换为'data.table'(setDT(df)
),melt
,并在patterns
中指定regex
=15=] 参数。删除 'names' 和 'address' 列的 NA
行。
library(data.table)#v1.9.5+
dM <- melt(setDT(df), measure=patterns(c('^name', '^adress')),
value.name=c('names', 'address') )
dM[!(is.na(names) & is.na(address))]
# id variable names address
#1: 1 1 John street a
#2: 2 1 Jack street b
#3: 3 1 Joey NA
#4: 1 2 Burt street d
#5: 2 2 Ben street e
#6: 3 2 Bob street f
#7: 1 3 chris street 1
#8: 2 3 connor street 2
或者我们可以使用 base R
中的 reshape
。
dM2 <- reshape(df, idvar='id', varying=list(grep('name', names(df)),
grep('adress', names(df))), direction='long')
在我们使用 is.na
.[=29= 创建逻辑索引后,通过使用标准 'data.frame' 索引,可以像 data.table
解决方案中那样删除 NA
行]
我有一个类似于以下数据框的数据,但每个组合都有大约十个字段,从 name1、adress1、city1 等开始
id name1 adress1 name2 adress2 name3 adress3
1 1 John street a Burt street d chris street 1
2 2 Jack street b Ben street e connor street 2
3 3 Joey <NA> Bob street f <NA> <NA>
现在我想重新排列这些数据,使其更有用,看起来应该是这样的,但包含它来自哪个条目的信息:
id origin names adresses
1 1 1 John street a
2 2 1 Jack street b
3 3 1 Joey <NA>
4 1 2 Burt street d
5 2 2 Ben street e
6 3 2 Bob street f
7 1 3 chris street 1
8 2 3 connor street 2
使用 tidyr 我可以获得长格式,但我有一个包含所有变量名称的键列,name1、name2、name3、street1 等。
我也尝试过使用单独的数据框,每个组合一个,例如一个用于名称的数据框,一个用于街道等。但是将所有内容重新组合在一起会导致错误的记录,因为您只能在 id 上加入,并且在长格式中会复制此 ID。我也一直在研究 Reshape2,但这会导致同样的问题。
我见过的所有从宽到长的转换都是当你有一个列要转换成的时候。我正在寻找 10 列的最终结果,或者如示例中的 2 列。
是否有我忽略的功能?
#code to generete the dataframes:
df <- data.frame(id = c(1,2,3),
name1 = c("John", "Jack", "Joey"),
adress1 = c("street a", "street b", NA),
name2 = c("Burt", "Ben", "Bob"),
adress2 = c("street d", "street e", "street f"),
name3 = c("chris", "connor", NA),
adress3 = c("street 1", "street 2", NA),
stringsAsFactors = FALSE)
expecteddf <- data.frame(id = c(1,2,3,1,2,3,1,2),
origin = c(rep(1, 3), rep(2, 3), rep(3, 2)),
names = c("John", "Jack", "Joey", "Burt", "Ben", "Bob", "chris", "connor"),
adresses = c("street a", "street b", NA, "street d", "street e", "street f", "street 1", "street 2"),
stringsAsFactors = FALSE
)
我们可以使用 data.table 的 devel
版本中的 melt
,它可以为 measure
列使用多个 patterns
。安装'data.table'开发版的说明是here
我们将'data.frame'转换为'data.table'(setDT(df)
),melt
,并在patterns
中指定regex
=15=] 参数。删除 'names' 和 'address' 列的 NA
行。
library(data.table)#v1.9.5+
dM <- melt(setDT(df), measure=patterns(c('^name', '^adress')),
value.name=c('names', 'address') )
dM[!(is.na(names) & is.na(address))]
# id variable names address
#1: 1 1 John street a
#2: 2 1 Jack street b
#3: 3 1 Joey NA
#4: 1 2 Burt street d
#5: 2 2 Ben street e
#6: 3 2 Bob street f
#7: 1 3 chris street 1
#8: 2 3 connor street 2
或者我们可以使用 base R
中的 reshape
。
dM2 <- reshape(df, idvar='id', varying=list(grep('name', names(df)),
grep('adress', names(df))), direction='long')
在我们使用 is.na
.[=29= 创建逻辑索引后,通过使用标准 'data.frame' 索引,可以像 data.table
解决方案中那样删除 NA
行]