2017-03-27 6 views
0

データフレームがありますが、一部の列はデータは同じですが、列名は異なります。重複した列を削除したいが、列名をマージする。たとえば、TEST1とTEST4列が重複している:重複した列名をマージする

df 

     test1 test2 test3 test4 
    1  1  1  0  1 
    2  2  2  2  2 
    3  3  4  4  3 
    4  4  4  4  4 
    5  5  5  5  5 
    6  6  6  6  6 

と私はこのようなものにするために、結果を希望:

​​

ここでのデータです:

structure(list(test1 = c(1, 2, 3, 4, 5, 6), test2 = c(1, 2, 4, 
4, 5, 6), test3 = c(0, 2, 4, 4, 5, 6), test4 = c(1, 2, 3, 4, 
5, 6)), .Names = c("test1", "test2", "test3", "test4"), row.names = c(NA, 
-6L), class = "data.frame") 

してください重複した列を単に削除するだけではないことに注意してください。また、重複が削除された後、重複した列の列名をマージしたい。

私が投稿したシンプルなテーブルでは手動で行うことができましたが、大きなデータセットでこれを使用したいのですが、どのカラムが同じであるかは事前にわかりません。 50個を超える重複カラムがある可能性があるので、手動でカラムを削除して名前を変更する必要はありません。

+2

大きなデータフレームで「rが重複した列を削除」。最初の数回のヒットが役に立たなかった理由を明確にしてください。さもなければ、この質問は重複として閉じられるでしょう。 – Henrik

+0

はい、持っています。結果表の列名を見てください。重複した列を削除したいだけではありません。また、重複が削除された後、重複した列の列名をマージしたい。私が投稿したシンプルなテーブルのために手動で行うこともできますが、これを大規模なデータセットに使用したいと思います。 – arielle

+0

どの列が重複しているかを事前に知っていますか?それとも、自動的に決定されるようにしたいのですか? – MichaelChirico

答えて

1

[OK]を改善しました。上記の回答は、hereのアイデアを使用して改善しました。重複列と重複しない列をデータフレームに保存します。重複していないものが重複と一致するかどうかを確認し、重複している場合は列名を連結します。これで、2つ以上の列が重複している場合にこれが機能します。

編集:変更summary~digest。これは、文字データに役立ちます。

df <- structure(list(test1 = c(1, 2, 3, 4, 5, 6), test2 = c(1, 2, 4, 
4, 5, 6), test3 = c(0, 2, 4, 4, 5, 6), test4 = c(1, 2, 3, 4, 
5, 6)), .Names = c("test1", "test2", "test3", "test4"), row.names = c(NA, 
-6L), class = "data.frame") 

library(digest) 
nondups <- df[!duplicated(lapply(df, digest))] 

dups <- df[duplicated(lapply(df, digest))] 

for(i in 1:ncol(nondups)){ 
    for(j in 1:ncol(dups)){ 
    if(FALSE %in% paste0(nondups[,i] == dups[,j])) NULL 
    else names(nondups)[i] <- paste(names(nondups[i]), names(dups[j]), sep = "+") 
    } 
} 

nondups 

関数として、実施例2、。

Editted:digestsummaryを変更し、非重複重複データフレームを返します。


Editted

age <- 18:29 height <- c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5) gender <- c("M","F","M","M","F","F","M","M","F","M","F","M") testframe <- data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender, gender3 = gender) dupcols <- function(df = testframe){ nondups <- df[!duplicated(lapply(df, digest))] dups <- df[duplicated(lapply(df, digest))] for(i in 1:ncol(nondups)){ for(j in 1:ncol(dups)){ if(FALSE %in% paste0(nondups[,i] == dups[,j])) NULL else names(nondups)[i] <- paste(names(nondups[i]), names(dups[j]), sep = "+") } } return(list(df1 = nondups, df2 = dups)) } dupcols(df = testframe) 

このセクションでは、新しいです。

例3:私たちは、あなたがGoogleで検索することを想定する必要があり

#Creating a 1500 column by 15000 row data frame 
dat <- do.call(data.frame, replicate(1500, rep(FALSE, 15000), simplify=FALSE)) 
names(dat) <- 1:1500 

#Fill the data frame with LETTERS across the rows 
#This part may take a while. Took my PC about 23 minutes. 
start <- Sys.time() 
    fill <- rep(LETTERS, times = ceiling((15000*1500)/26)) 
    j <- 0 
    for(i in 1:nrow(dat)){ 
    dat[i,] <- fill[(1+j):(1500+j)] 
    j <- j + 1500 
    } 
difftime(Sys.time(), start, "mins") 

#Run the function on the created data set 
#This took about 4 minutes to complete on my PC. 
start <- Sys.time() 
    result <- dupcols(df = dat) 
difftime(Sys.time(), start, "mins") 

names(result$df1) 
ncol(result$df1) 
ncol(result$df2) 
+0

きれいに動作するようです。 – arielle

+0

非常に大きなデータフレーム、たとえば15000 x 1500でこれを実行するには、しばらく時間がかかると思いますか? – arielle

+0

テストしてください。私が提供した例を使用し、データフレームを多数回複製すると、それはかなり迅速に機能します。 'dfnew <-do.call(" data.frame "、replicate(500、testframe、simplify = FALSE)); ncol(dfnew); start < - Sys.time(); 結果< - dupcols(df = dfnew); difftime(Sys.time()、start、 "secs"); '列名は扱いにくいです。 – Jake

0

完全に自動化されているわけではありませんが、ループの出力によって重複列のペアが識別されます。重複した列の1つを削除してから、重複した列に基づいて名前を変更する必要があります。

df <- structure(list(test1 = c(1, 2, 3, 4, 5, 6), test2 = c(1, 2, 4, 
4, 5, 6), test3 = c(0, 2, 4, 4, 5, 6), test4 = c(1, 2, 3, 4, 
5, 6)), .Names = c("test1", "test2", "test3", "test4"), row.names = c(NA, 
-6L), class = "data.frame") 

for(i in 1:(ncol(df)-1)){ 
    for(j in 2:ncol(df)){ 
    if(i == j) NULL 
    else if(FALSE %in% paste0(df[,i] == df[,j])) NULL 
    else print(paste(i, j, sep = " + ")) 
    } 
} 

new <- df[,-4] 
names(new)[1] <- paste(names(df[1]), names(df[4]), sep = "+") 
new 
+0

これは良いスタートだと思われますが、すべての可能なペアを探すので、同じデータを持つ2つ以上の列がある場合は機能しません... – arielle

+0

そして、 50個以上の重複カラムがある可能性があるので、カラムを手動で削除したり名前を変更したりする必要がない方法を探してください。 – arielle

関連する問題