以变量值成为变量名并且它们的值从另一列中选取的方式重塑数据集
Reshaping dataset in a way that values for variables become variable names and their values are picked from another column
--------------------新 POST:
我过去发布了不正确的数据示例(留在下面)。实际上,我的数据在同一列下有重复的“模块”,以前的解决方案对我的问题不起作用。
我的示例数据(当前数据集):
Year <- c("2013", "2020", "2015", "2012")
Grade <- c(28, 39, 76, 54)
Code <- c("A", "B", "C", "A")
Module1 <- c("English", "English", "Science", "English")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("History", "History", "History", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("Art", "Geography", "Math", "Geography")
Results3 <- c(89, 84, 45, 67)
Module14 <- c("Math", "Math", "Geography", "Art")
Results14 <- c(89, 24, 95, 67)
Module15 <-c("Science", "Art", "Art", "Science")
Results15 <-c(87, 24, 25, 67)
daf <- data.frame(Id, Year, Grade, Code, Module1, Results1, Module2, Results2, Module3, Results3, Module14, Results14, Module15, Results15)
我的目标-我需要达到的数据集:
Year <- c("2013", "2020", "2015", "2012")
Grade <- c(28, 39, 76, 54)
Code <- c("A", "B", "C", "A")
English <- c(45, 58,NA,54)
Math <- c(89, 24,45, NA)
Science <- c(87, NA, 34, 67)
Geography <- c(NA, 84, 95,67)
Art <- c(89,24,25,45)
wished_df <- data.frame(Id, Year, Grade, Code, English, Math, Science,Geography, Art)
再次感谢您的帮助!
-------------------------------- 老 POST:
我正在尝试将我当前的数据重塑为新格式。
Module1 <- c("English", "Math", "Science", "Geography")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("Math", "History", "English", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("History", "Art", "English", "Geography")
Results3 <- c(89, 84, 45, 67)
daf <- data.frame(Module1, Results1, Module2, Results2, Module3, Results3)
我需要的是将模块名称设置为“变量名称”,并将模块结果设置为“变量名称的值”,如下所示:
English1 <- c(45, 98, 45)
Math1 <- c(58, 12, NA)
Science1 <- c(34, NA, NA)
Geography1 <- c(54,NA, 67)
Art1 <- c(NA, 45, 84)
wished_df <- data.frame(English1, Math1, Science1,Geography1, Art1)
感谢您的任何想法。
1) reshape 使用最后注释中的数据,将输入列名称分成两组(模块列和结果列),给出 varying
。使用该 reshape 到长格式,其中 varying=
定义输入中的哪些列对应于长格式中的单个列。 v.names=
指定用于从不同列生成的两列中的每一列的名称。 reshape
将给出一个包含时间列、模块列、结果列和 ID 列的数据框。我们不需要 id
列,所以使用 [-4].
删除它
然后将其重塑回新的宽幅形式。 idvar=
指定输出行的来源,timevar=
指定输出列的来源。其他一切都是结果的主体。 reshape 将生成一个我们不需要的时间列,因此使用 [-1] 将其删除。最后我们删除了每个列名的垃圾部分。
没有使用包。
varying <- split(names(daf), sub("\d+$", "", names(daf)))
long <- reshape(daf, dir = "long", varying = varying, v.names = names(varying))[-4]
wide <- reshape(long, dir = "wide", idvar = "time", timevar = "Module")[-1]
names(wide) <- sub(".*[.]", "", names(wide))
给予:
> wide
English Math Science Geography History Art
1.1 45 58 34 54 NA NA
1.2 98 12 NA NA 67 45
1.3 45 NA NA 67 89 84
2)pivot_使用末尾Note中的数据,指定使用所有列,使用.names
指定long中的列名形式取自输入的列名的第一部分,其中输入的名称根据 names_pattern=
正则表达式拆分。然后转到一个新的宽格式,其中列名取自“模块”列,结果正文中的值取自“结果”列。索引列将定义行,之后可以省略。
library(dplyr)
library(tidyr)
daf %>%
pivot_longer(everything(), names_to = c(".value", "index"),
names_pattern = "(\D+)(\d+)") %>%
pivot_wider(names_from = Module, values_from = Results) %>%
select(-index)
给予:
# A tibble: 3 x 6
English Math History Art Science Geography
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 45 58 NA NA 34 54
2 98 12 67 45 NA NA
3 45 NA 89 84 NA 67
3) unlist/tapply UUsing the data in the end of the Note, another base solution can be fashed by 单独取消列出模块和结果列以获得长形式并使用 tapply 转换为宽形式。没有使用包
is_mod <- grepl("Module", names(daf))
long <- data.frame(Module = unlist(daf[is_mod]), Results = unlist(daf[!is_mod]))
tab <- tapply(long$Results, list(sub("\d+$", "", rownames(long)), long$Module), sum)
as.data.frame.matrix(tab)
给予:
Art English Geography History Math Science
Module1 NA 45 54 NA 58 34
Module2 45 98 NA 67 12 NA
Module3 84 45 67 89 NA NA
备注
Module1 <- c("English", "Math", "Science", "Geography")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("Math", "History", "English", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("History", "Art", "English", "Geography")
Results3 <- c(89, 84, 45, 67)
daf <- data.frame(Module1, Results1, Module2, Results2, Module3, Results3)
A data.table
版本:
library(data.table)
library(magrittr)
dt <- as.data.table(daf)
dt %>%
melt.data.table(measure.vars = patterns("^Module", "^Result")) %>%
dcast.data.table(variable ~ ..., value.var = "value2")
给予:
Key: <variable>
variable Art English Geography History Math Science
<fctr> <num> <num> <num> <num> <num> <num>
1: 1 NA 45 54 NA 58 34
2: 2 45 98 NA 67 12 NA
3: 3 84 45 67 89 NA NA
--------------------新 POST: 我过去发布了不正确的数据示例(留在下面)。实际上,我的数据在同一列下有重复的“模块”,以前的解决方案对我的问题不起作用。
我的示例数据(当前数据集):
Year <- c("2013", "2020", "2015", "2012")
Grade <- c(28, 39, 76, 54)
Code <- c("A", "B", "C", "A")
Module1 <- c("English", "English", "Science", "English")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("History", "History", "History", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("Art", "Geography", "Math", "Geography")
Results3 <- c(89, 84, 45, 67)
Module14 <- c("Math", "Math", "Geography", "Art")
Results14 <- c(89, 24, 95, 67)
Module15 <-c("Science", "Art", "Art", "Science")
Results15 <-c(87, 24, 25, 67)
daf <- data.frame(Id, Year, Grade, Code, Module1, Results1, Module2, Results2, Module3, Results3, Module14, Results14, Module15, Results15)
我的目标-我需要达到的数据集:
Year <- c("2013", "2020", "2015", "2012")
Grade <- c(28, 39, 76, 54)
Code <- c("A", "B", "C", "A")
English <- c(45, 58,NA,54)
Math <- c(89, 24,45, NA)
Science <- c(87, NA, 34, 67)
Geography <- c(NA, 84, 95,67)
Art <- c(89,24,25,45)
wished_df <- data.frame(Id, Year, Grade, Code, English, Math, Science,Geography, Art)
再次感谢您的帮助!
-------------------------------- 老 POST: 我正在尝试将我当前的数据重塑为新格式。
Module1 <- c("English", "Math", "Science", "Geography")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("Math", "History", "English", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("History", "Art", "English", "Geography")
Results3 <- c(89, 84, 45, 67)
daf <- data.frame(Module1, Results1, Module2, Results2, Module3, Results3)
我需要的是将模块名称设置为“变量名称”,并将模块结果设置为“变量名称的值”,如下所示:
English1 <- c(45, 98, 45)
Math1 <- c(58, 12, NA)
Science1 <- c(34, NA, NA)
Geography1 <- c(54,NA, 67)
Art1 <- c(NA, 45, 84)
wished_df <- data.frame(English1, Math1, Science1,Geography1, Art1)
感谢您的任何想法。
1) reshape 使用最后注释中的数据,将输入列名称分成两组(模块列和结果列),给出 varying
。使用该 reshape 到长格式,其中 varying=
定义输入中的哪些列对应于长格式中的单个列。 v.names=
指定用于从不同列生成的两列中的每一列的名称。 reshape
将给出一个包含时间列、模块列、结果列和 ID 列的数据框。我们不需要 id
列,所以使用 [-4].
然后将其重塑回新的宽幅形式。 idvar=
指定输出行的来源,timevar=
指定输出列的来源。其他一切都是结果的主体。 reshape 将生成一个我们不需要的时间列,因此使用 [-1] 将其删除。最后我们删除了每个列名的垃圾部分。
没有使用包。
varying <- split(names(daf), sub("\d+$", "", names(daf)))
long <- reshape(daf, dir = "long", varying = varying, v.names = names(varying))[-4]
wide <- reshape(long, dir = "wide", idvar = "time", timevar = "Module")[-1]
names(wide) <- sub(".*[.]", "", names(wide))
给予:
> wide
English Math Science Geography History Art
1.1 45 58 34 54 NA NA
1.2 98 12 NA NA 67 45
1.3 45 NA NA 67 89 84
2)pivot_使用末尾Note中的数据,指定使用所有列,使用.names
指定long中的列名形式取自输入的列名的第一部分,其中输入的名称根据 names_pattern=
正则表达式拆分。然后转到一个新的宽格式,其中列名取自“模块”列,结果正文中的值取自“结果”列。索引列将定义行,之后可以省略。
library(dplyr)
library(tidyr)
daf %>%
pivot_longer(everything(), names_to = c(".value", "index"),
names_pattern = "(\D+)(\d+)") %>%
pivot_wider(names_from = Module, values_from = Results) %>%
select(-index)
给予:
# A tibble: 3 x 6
English Math History Art Science Geography
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 45 58 NA NA 34 54
2 98 12 67 45 NA NA
3 45 NA 89 84 NA 67
3) unlist/tapply UUsing the data in the end of the Note, another base solution can be fashed by 单独取消列出模块和结果列以获得长形式并使用 tapply 转换为宽形式。没有使用包
is_mod <- grepl("Module", names(daf))
long <- data.frame(Module = unlist(daf[is_mod]), Results = unlist(daf[!is_mod]))
tab <- tapply(long$Results, list(sub("\d+$", "", rownames(long)), long$Module), sum)
as.data.frame.matrix(tab)
给予:
Art English Geography History Math Science
Module1 NA 45 54 NA 58 34
Module2 45 98 NA 67 12 NA
Module3 84 45 67 89 NA NA
备注
Module1 <- c("English", "Math", "Science", "Geography")
Results1 <- c(45, 58, 34, 54)
Module2 <- c("Math", "History", "English", "Art")
Results2 <- c(12, 67, 98, 45)
Module3 <- c("History", "Art", "English", "Geography")
Results3 <- c(89, 84, 45, 67)
daf <- data.frame(Module1, Results1, Module2, Results2, Module3, Results3)
A data.table
版本:
library(data.table)
library(magrittr)
dt <- as.data.table(daf)
dt %>%
melt.data.table(measure.vars = patterns("^Module", "^Result")) %>%
dcast.data.table(variable ~ ..., value.var = "value2")
给予:
Key: <variable>
variable Art English Geography History Math Science
<fctr> <num> <num> <num> <num> <num> <num>
1: 1 NA 45 54 NA 58 34
2: 2 45 98 NA 67 12 NA
3: 3 84 45 67 89 NA NA