2016-10-31 10 views
1

これは私の最初の投稿です。私はデータの争いのビットを困惑しています。いくつかのデータ処理の後、私は1つのデータフレームを残して、複数のデータフレームを列のペアで分割し、最終的に関連する比例順位のIDの単一のデータフレームにマージします。は、1つのデータフレームを連続したペアで多数のデータフレームに分割します。

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)の各対はID番号(VARA)からなる

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 

および比例ランキング(varA1)。列は異なる長さです(ただし、関連するペアの2つの列の長さは同じです)。 UPDATE: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

Reduce(function(...) merge(..., by = 1, all = TRUE), varlist) 

にデータフレームのすべてをマージしかし、あなたはこの 'lapply(grep(" var [[:upper:])$ "、names(df)、value = TRUE)、function(x)df [c(x、paste0 、1)))) '。質問については、1) 'var'のいくつかは長さが違うと言いますが、データフレームは同じ長さでなければなりません。欠けているデータのためにNAsを持っていますか? 2)与えられた 'var'に対してIDのどれかがそれ自身を繰り返しますか? 3)すべての 'var'はすべてのIDを持っていますか?これらの問題とその対処法を説明するために、例を更新してください。 – Barker

+0

@ Hack-R私は再現可能な例を追加しました。ありがとうございました。 – zhg

+0

@Barker例を調整しました。なぜなら、(1)はい、私は空のセルにNAを持っています。 (2)いいえ、例に示すように、与えられた 'var'に対してIDは何も繰り返されません。 (3)いいえ、すべての 'var'がすべてのIDを持っているわけではありません。ありがとうございました! – zhg

答えて

0

ここtidyverseオプションです:

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 
0

たちはdata.tableからmelt/dcastを使用してこれを行うことができます。 'data.frame'を 'data.table'(setDT(df))に変換するには、meltを使用して 'long'形式(meltからdata.tableまでは複数measurepatternsを取ることができます)に変更し、最後にdcast

library(data.table) 
nm <- names(df)[c(TRUE, FALSE)] 

dcast(melt(setDT(df), measure = patterns("[A-Z]$", "\\d+$"), 
    value.name = c("ID", "value"), na.rm = TRUE)[, 
    Var := nm[variable]], ID~Var, value.var = "value") 
# ID varA varB varC 
#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 
0

ベースrのみ。以下に示すコードを組み合わせて1行で実行することもできますが、何が起こっているのかを簡単に理解できるように分割します。

は、リストの別々の要素に変数を得るためにあなたのvar変数

varnames <- grep("var[[:upper:]]$",names(df), value = TRUE) 

インデックスあなたのデータフレームを見つけるためにはgrepを使用します。 na.omitは、空の行を削除します。

varlist <- lapply(varnames, function(x) na.omit(df[c(x,paste0(x,1))])) 

私は完全な答えを提出したい前に、私はあなたのデータに関するいくつかの質問を持っている単一のデータフレームの1つのライン

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))]))) 
関連する問題