以变​​量值成为变量名称的方式重塑数据集,并且它们的值是从另一列中选取的 我的示例数据当前数据集:我的目标 - 我需要实现的数据集:

问题描述

-------------------新帖子: 我过去发布过不正确的数据示例(将其留在下面)。实际上,我的数据在同一列下有重复的“模块”,以前的解决方案对我的问题不起作用。

我的示例数据(当前数据集):

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","Art")
Results2 <- c(12,67,98,45)
Module3 <- c("Art","Geography","Math","Geography")
Results3 <- c(89,84,45,67)
Module14 <- c("Math","Art")
Results14 <- c(89,24,95,67)
Module15 <-c("Science","Art","Science")
Results15 <-c(87,25,67)

daf <- data.frame(Id,Year,Grade,Code,Module1,Results1,Module2,Results2,Module3,Results3,Module14,Results14,Module15,Results15)

我的目标 - 我需要实现的数据集:

Year <- c("2013","A")
English <- c(45,NA,54)
Math <- c(89,NA)
Science <- c(87,67)
Geography <- c(NA,67)
Art <- c(89,45)

wished_df <- data.frame(Id,English,Math,Science,Geography,Art)

再次感谢您的帮助!

-------------------------------- 旧帖子: 我正在尝试将当前数据重塑为新格式。

Module1 <- c("English","Geography")
Results1 <- c(45,54)
Module2 <- c("Math",45)
Module3 <- c("History",67)

daf <- data.frame(Module1,Results3)

我需要的是将模块名称设置为“变量名称”,并将模块结果设置为“变量名称的值”,如下所示:

English1 <- c(45,45)
Math1 <- c(58,12,NA)
Science1 <- c(34,NA)
Geography1 <- c(54,67)
Art1 <- c(NA,84)

wished_df <- data.frame(English1,Math1,Science1,Geography1,Art1)

感谢您的任何想法。

解决方法

1) reshape 使用末尾注释中的数据,将输入列名称分成两组(模块列和结果列),给出 varying。使用该重塑为长格式,其中 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_ 使用最后的注释中的数据,指定要使用所有列,使用 .names 指定长格式的列名取自输入的列名的第一部分,其中输入的名称根据 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 U使用末尾注释中的数据,可以通过单独取消列出 Module 和 Results 列来获得长格式并使用 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","Geography")
Results3 <- c(89,84,45,67)
daf <- data.frame(Module1,Results1,Module2,Results2,Module3,Results3)
,

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