这是我在这里的第一篇文章。我对一些数据争论感到难过。在进行一些数据处理之后,我留下了一个数据帧,我希望通过成对列分成多个数据帧,并最终合并到具有相关比例排名的ID的单个数据帧中。
以下是一个示例数据框:
dput(
varA<-c(1,3,4,2,5,NA,NA)
varA1<-c(.99,.95,.93,.89,.84,NA,NA)
varB<-c(5,2,1,3,4,NA,NA)
varB1<-c(.96,.93,.91,.85,.83,NA,NA)
varC<-c(3,4,1,5,2,6,7)
varC1<-c(.92,.91,.90,.82,.79,.72,.69)
df<-data.frame(varA,varA1,varB,varB1,varC,varC1))
具有以下结构:
varA varA1 varB varB1 varC varC1
001 .99 005 .96 003 .92
003 .95 002 .93 004 .91
004 .93 001 .91 001 .90
002 .89 003 .85 005 .82
005 .84 004 .83 002 .79
NA NA NA NA 006 .72
NA NA NA NA 007 .69
每对列(例如varA&amp; varA1)由ID号(varA)和比例排序(varA1)组成。列是不同的长度(尽管相关对中的两列中的每一列具有相等的长度)。更新:ID不会在列中重复,但并非所有ID都包含在每列中。
最终,我希望有一个数据框,每行作为ID,并在每列中显示比例值。如:
ID varA1 varB1 varC1
001 .99 .91 .90
002 .89 .93 .79
003 .95 .85 .92
004 .93 .83 .91
005 .84 .96 .82
006 NA NA .72
007 NA NA .69
据我所知,实现这一目标的显而易见的方法是将ID和比例的数据帧拆分为多个数据帧,然后根据公共ID列进行合并。
但是,我无法弄清楚如何以有效的方式拆分这样的数据帧。
使这个棘手的是ID的顺序 - 排名 - 是重要的信息。我能够计算每个排名的比例值(并按照概述将其存储在列表中),但是当我将这些ID和列表中的排名转换为我可以结合的格式时,我感到很难过。它与其他与每个ID相关的数据。
感谢您的任何建议!
答案 0 :(得分:0)
这是一个整齐的选择:
library(tidyverse)
# rebind odd and even columns
bind_cols(df %>% select(matches('\\D$')) %>% gather(var, id), # gather odd cols to long
df %>% select(matches('\\d$')) %>% gather(var1, val)) %>% # gather even cols
select(-var) %>% # drop duplicate var name
drop_na(id) %>% # drop rows with no ID
spread(var1, val) # spread to wide form
#> id varA1 varB1 varC1
#> 1 1 0.99 0.91 0.90
#> 2 2 0.89 0.93 0.79
#> 3 3 0.95 0.85 0.92
#> 4 4 0.93 0.83 0.91
#> 5 5 0.84 0.96 0.82
#> 6 6 NA NA 0.72
#> 7 7 NA NA 0.69
答案 1 :(得分:0)
我们可以使用melt/dcast
中的data.table
来执行此操作。将'data.frame'转换为'data.table'(setDT(df)
),使用melt
将其重新整形为'long'格式(来自melt
的{{1}}可以使用多个data.table
measure
),最后使用patterns
将其重新整理为“广泛”格式。
dcast
答案 2 :(得分:0)
仅限r
。我下面的代码可以组合在一行中运行,但我会将它们分开以便更容易理解正在发生的事情。
使用grep查找var
变量
varnames <- grep("var[[:upper:]]$",names(df), value = TRUE)
索引数据框以将变量转换为列表的单独元素。 na.omit
删除空行。
varlist <- lapply(varnames, function(x) na.omit(df[c(x,paste0(x,1))]))
将所有数据帧合并为一个数据框
Reduce(function(...) merge(..., by = 1, all = TRUE), varlist)
在一行
Reduce(function(...) merge(..., by = 1, all = TRUE),
lapply(grep("var[[:upper:]]$",names(df), value = TRUE),
function(x) na.omit(df[c(x,paste0(x,1))])))