2017-03-10 1 views
3

내가 다른 행의 수와 데이터 프레임의 목록 from (dfAdfB)가 프레임 정렬 한 번에 모든 목록? 올바르게 이해하면 코드가 정렬 된 데이터 프레임 목록 ("와이드"형식)을 반환합니다. 그런 다음 목록을 새 데이터 프레임으로 변환해야합니다.데이터의 목록에있는 각 데이터 프레임은

(또 다른 문제는 목록의 모든 df에 대해 ID 번호, Var1, Var2, Var3 ...와 같은 이름의 변수가 있음)이 문제를 재현 할 수 없습니다.

감사합니다.

내 코드는 다음과 같습니다

여기
genSeq <- c('https://raw.githubusercontent.com/ANHIG/IMGTHLA/Latest/alignments/A_gen.txt') 

# Read raw data as character vector 
a <- readLines(genSeq) 

# Some diagnostics 
# is.vector(a) 
# typeof(a) 
# length(a) 

# Convert vector a to data frame b 
b <- as.data.frame(a, stringsAsFactors = FALSE) 
# is.data.frame(b) 
# typeof(a) 
# length(a) 

# Install some packages 
    install.packages("stringr") 
    install.packages("stringi") 
    install.packages("xlsx") 

# Load the packages 
library(stringr) 
library(stringi) 
library(xlsx) 

# Read the lines with nucleotide sequences 
bb <- b[c(9:19762),] 

# Some diagnostics 
# head(bb) 
# tail(bb) 
# length(bb) 
# typeof(bb) 
# is.vector(bb) 

# Split lines 
d <- strsplit(bb, split = "") 

# Some diagnostics 
# head(d) 
# tail(d) 
# length(d) 
# typeof(d) 
# is.vector(d) 

# Count number of variables (http://stackoverflow.com/a/15201478/1009306) 
max.length <- max(sapply(d, length)) 

# Add NA values to list elements when the lists are shorter than others 
d <- lapply(d, function(x) {c(x, rep(NA, max.length-length(x)))}) 

# Combine all elements 
do.call(rbind, d) 

# Some diagnostics 
# head(d) 
# tail(d) 
# length(d) 
# typeof(d) 
# is.vector(d) 


# Transform matrix 
dd <- t(matrix(unlist(d),ncol=length(d))) 

# Some diagnostics 
# head(dd) 
# tail(dd) 
# is.matrix(dd) 

# Transform existing dd matrix into ddd data frame 
ddd <- as.data.frame(dd) 

# Some diagnostics 
# head(ddd) 
# tail(ddd) 
# is.data.frame(ddd) 
# typeof(ddd) 
# length(ddd) 
# class(ddd) 
# str(ddd) 
# names(ddd) 
# nrow(ddd) 
# ncol(ddd) 
# summary(ddd) 

# Add new variable allel by concatenating values in existing variables V1...v19 
ddd <- transform(ddd, allel = paste0(ddd$V1, ddd$V2, ddd$V3, ddd$V4, ddd$V5, ddd$V6, ddd$V7, ddd$V8, ddd$V9, ddd$V10, ddd$V11, ddd$V12, ddd$V13, ddd$V14, ddd$V15, ddd$V16, ddd$V17, ddd$V18, ddd$V19, sep = " ")) 

# Some diagnostics 
# names(ddd) 

# Reorder variable allel to be the first 
new_ordered <- ddd[c(length(ddd),c(1:(length(ddd)-1)))] 

# Some diagnostics 
# names(new_ordered) 
# ncol(new_ordered) 

# Remove unnecessary variables V1...V19 
new_ordered$V1 <- NULL 
new_ordered$V2 <- NULL 
new_ordered$V3 <- NULL 
new_ordered$V4 <- NULL 
new_ordered$V5 <- NULL 
new_ordered$V6 <- NULL 
new_ordered$V7 <- NULL 
new_ordered$V8 <- NULL 
new_ordered$V9 <- NULL 
new_ordered$V10 <- NULL 
new_ordered$V11 <- NULL 
new_ordered$V12 <- NULL 
new_ordered$V13 <- NULL 
new_ordered$V14 <- NULL 
new_ordered$V15 <- NULL 
new_ordered$V16 <- NULL 
new_ordered$V17 <- NULL 
new_ordered$V18 <- NULL 
new_ordered$V19 <- NULL 

# Some diagnostics 
# ncol(new_ordered) 
# nrow(new_ordered) 

# Remove rows containing NA (http://stackoverflow.com/q/8005154/1009306) 
new_ordered <- subset(new_ordered, !(V50 == "NA" & V100 == "NA")) 

# Some diagnostics 
# head(new_ordered) 
# ncol(new_ordered) 
# nrow(new_ordered) 


# Shrink whitespaces in allel names with the help of library(stringr)'s function: 
new_ordered$allel <- gsub(" ", "", new_ordered$allel) 




# The list of unique allels accordingly to LL*NN:NN(NL) template 
##### 

# Sort new_ordered data frame in an ascending order by allel variable 
new_odrd_srtd <- new_ordered[order(new_ordered$allel),] 

# Some diagnostics 
# head(new_odrd_srtd) 
# typeof(new_odrd_srtd) 
# is.data.frame(new_odrd_srtd) 

# The list of unique allel names 
unique.allels <- unique(new_odrd_srtd$allel) 

# Let the list to be a character vector 
unique.allels <- as.character(unique.allels) 

# Show them: 
# unique.allels 

# Their number is: 
# length(unique.allels) 

# Export them into MS Excel workbook: 
# write.xlsx(unique.allels, file="d:/hla.xlsx", sheetName="01 unique.allels", append=TRUE) 

# Extract the part of an allel name considering specific HLA protein only: LL*NN:NN(NL). 
# The final point for the pattern of interest is cleared at http://r.789695.n4.nabble.com/Extract-part-of-string-tp4683108p4683111.html 
specific.HLA.protein <- unique(gsub("^.*(\\A\\*[0-9A-Za-z]*\\:[0-9A-Za-z]*).*$", "\\1", unique.allels)) 

# Show them: 
# specific.HLA.protein 

# Their number is: 
# length(specific.HLA.protein) 

# Export them into _the same_ MS Excel workbook 
# write.xlsx(specific.HLA.protein, file="d:/hla.xlsx", sheetName="02 specific.HLA.protein", append=TRUE) 













################################################################################## 
# Plan 
# 
# convert multiple rows per subject into single row 
# Create data frame with these long rows 
# Concatenate values of each variable into corresponding single cells of a new row 
# 
# 
# Example for http://stackoverflow.com/q/42711357 
##### 

# data frame A 
IDA <- c("a", "a", "a") 
Var1 <- c("1","4",".") 
Var2 <- c("2"," ","8") 
Var3 <- c("3","6","9") 

# data frame B 
IDB <- c("b", "b") 
Var4 <- c("11","44") 
Var5 <- c("22"," ") 
Var6 <- c("33","66") 

# Create data frames and check their structures  
dfA <- data.frame(IDA, Var1, Var2, Var3) 
is.data.frame(dfA) 
dfB <- data.frame(IDB, Var4, Var5, Var6) 
is.data.frame(dfB) 

# Create a list of data frames 
from <- list(dfA, dfB) 
from 

# Check its type 
is.list(from) 

# Read each elements of the list one by one 
from[[1]] 
from[[2]] 

# Arrange only any single element of the list to get the desired structure: 
trnsp.dfA <- t(c(t(from[[1]]))) 
trnsp.dfA 
trnsp.dfB <- t(c(t(from[[2]]))) 
trnsp.dfB 


l2 <- lapply(from, function(i) t(c(t(i)))) 
l2 <- lapply(l2, `length<-`, max(lengths(l2))) 

new_df <- setNames(data.frame(do.call(rbind, l2)), c('ID', paste0('Var', seq(max(lengths(l2))-1)))) 
new_df 


# Some diagnostics 
diagnostic <- new_df 
head(diagnostic) 
tail(diagnostic) 
is.data.frame(diagnostic) 
typeof(diagnostic) 
length(diagnostic) 
class(diagnostic) 
str(diagnostic) 
names(diagnostic) 
nrow(diagnostic) 
ncol(diagnostic) 
summary(diagnostic) 


################################################################################## 
# End of Example 

# Select strings only for A*01:01:01:01 allel 
new_odrd_srtd_sbst <- subset(new_odrd_srtd, grepl("A\\*01:01:01*\\:*[0-9A-Za-z]", allel)) 
# A regular expression for the pattern with spaces plus extra info: 
# new_odrd_srtd_sbst <- subset(new_odrd_srtd, grepl("^.*(\\A\\*[0-9A-Za-z]*\\:0[1-2]).*$", allel)) 
head(new_odrd_srtd_sbst) 

unique(new_odrd_srtd_sbst$allel) 




# Add new vaiable allelGroup_specific.HLA.protein by copying values in existing variable allel 
new_odrd_srtd_sbst <- transform(new_odrd_srtd_sbst, allelGroup_specific.HLA.protein = paste0(new_odrd_srtd_sbst$allel)) 

# Reorder variables 
new_odrd_srtd_sbst_added_ordrd <- new_odrd_srtd_sbst[c(length(new_odrd_srtd_sbst), c(1:(length(new_odrd_srtd_sbst)-1)))] 

# Extract the part of an allel name considering specific HLA protein only: A*NN:NN(NL). 
# The final point for the pattern of interest is cleared here: http://r.789695.n4.nabble.com/Extract-part-of-string-tp4683108p4683111.html 
new_odrd_srtd_sbst_added_ordrd$allelGroup_specific.HLA.protein <- gsub("^.*(\\A\\*[0-9A-Za-z]*\\:[0-9A-Za-z]*).*$", "\\1", new_odrd_srtd_sbst_added_ordrd$allelGroup_specific.HLA.protein) 

# Diagnostic 
is.data.frame(new_odrd_srtd_sbst_added_ordrd) 
typeof(new_odrd_srtd_sbst_added_ordrd) 


# Split dataframe into a list of data frames based on a value in allel variable 
# http://stackoverflow.com/q/18527051 
ndf <- split(new_odrd_srtd_sbst_added_ordrd, new_odrd_srtd_sbst_added_ordrd$allel) 
ndf[[1]][1:36,1:25] 

# Diagnostic 
is.data.frame(ndf) 
typeof(ndf) 
class(ndf) 
length(ndf) 

# From this step I fail to step further... 
+0

당신은 당신의 예를 재현 할시겠습니까? ('dput()'사용) – Sotos

+0

내가 그랬다. 귀하의 제안에 감사드립니다. – stan

+1

원하는 출력은 무엇입니까? 한 행의 데이터 프레임 또는 한 개의 데이터 프레임과 한 개의 데이터 프레임을 가진 목록을 원하십니까? 가장 중요한 것은 왜 왜 그런 이상한 데이터 구조가 필요할까요? –

답변

3

하나의 가능성

l2 <- lapply(from, function(i) as.vector(c(as.character(i[1,1]), t(c(t(i[-1])))))) 
l2 <- lapply(l2, `length<-`, max(lengths(l2))) 

new_df <- setNames(data.frame(do.call(rbind, l2)), 
        c('ID', paste0('Var', seq(max(lengths(l2))-1)))) 

new_df 
# ID Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 
#1 a 1 2 3 4   6 . 8 9 
#2 b 11 22 33 44  66 <NA> <NA> <NA> 

당신은 물론 당신의 요구 사항에하지 않은 i[1,1]으로 연결을 피할 수있는 것이 아니라 내가 생각했던 광산의 추가이다 여기에 적용될 수 있습니다. 그래서,이를 피하고 원래 전치 기능을 유지하여, 당신은

l2 <- lapply(from, function(i) t(c(t(i)))) 
l2 <- lapply(l2, `length<-`, max(lengths(l2))) 

new_df <- setNames(data.frame(do.call(rbind, l2)), 
        c('ID', paste0('Var', seq(max(lengths(l2))-1)))) 

new_df 
# ID Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 
#1 a 1 2 3 a 4   6 a .  8  9 
#2 b 11 22 33 b 44  66 <NA> <NA> <NA> <NA> 

은 세 단계로이를 평가 해보십시오. 귀하의 예를 다음
l3 <- lapply(from, function(i) t(c(t(i[-1])))) 
l3 <- lapply(l3, `length<-`, max(lengths(l3))) 

new_df1 <- setNames(data.frame(do.call(rbind, l3)), 
        paste0('Var', seq(max(lengths(l3))))) 

new_df1 
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 
#1 1 2 3 4   6 . 8 9 
#2 11 22 33 44  66 <NA> <NA> <NA> 

모든 고유 ID를 추출 첫째는 ID가없이 데이터 프레임을 생성

, 함께 바인딩

i1 <- sapply(from, function(i) unique(as.character(i[[1]]))) 
i1 
#[1] "a" "b" 

,

final_df1 <- cbind(IDs = i1, new_df1) 

final_df1 
# IDs Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 
#1 a 1 2 3 4   6 . 8 9 
#2 b 11 22 33 44  66 <NA> <NA> <NA> 
+0

예제 목록에서 완벽하게 작동합니다 :). 그러나 실제 데이터에는 오류 'i [1, 1]의 오류 : 잘못된 치수 수'가 표시됩니다. 어떤 힌트? 감사합니다. – stan

+0

어쩌면'unique'? 아마도'lapply (from, function (i) as.vector (c (unique (as.character (i [, 1))), t (c (t (i [-1 ])))))' – Sotos

+0

음, 작동하지 않습니다. Sotos, 당신은 단계별로 설명 할 수 있을까요? 기능 (i) as.vector (c (as.character (i [1,1]), t (c (t [i [-1])))))) '할거야? – stan

3

:

당신은 당신이 이미 각 개별 data.frame에 무엇을하고 있는지 수행 할 list의 모든 data.frame 반복하는 lapply을 사용할 수 있습니다처럼 691,363,210
library(data.table) 
# Create a list of data frames 
from <- list(dfA, dfB) 
from 
[[1]] 
    IDA Var1 Var2 Var3 
1 a 1 2 3 
2 a 4   6 
3 a . 8 9 

[[2]] 
    IDB Var4 Var5 Var6 
1 b 11 22 33 
2 b 44   

# rbind all the elements in the list of data.tables 
    out <- lapply(from, function(x){as.data.table(t(c(t(x))))}) 
    out <- rbindlist(out, fill = TRUE) 
    out 
     V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
    1: a 1 2 3 a 4  6 a . 8 9 
    2: b 11 22 33 b 44 66 NA NA NA NA 

# If the files are stored on your drive, you can call them by bulk, and then `rbindlist`: 

    files <- list.files(pattern = ".csv") 
    files <- lapply(files, fread) 
+0

답변 해 주셔서 감사합니다. 그러나'library (data.table)'라이브러리를 실행하면'data.table '이라는 패키지가 존재합니다.'install.packages (data.table)'을 실행하면'data.table '이라는 패키지가 없습니다. 다른 하나는'install.packages : object 'data.table'not found '에 오류가 나타납니다. – stan

+1

어떤 버전이나 R을 사용하고 있는지 모르겠습니다. 답을 업데이트하고'R.Version() $ version.string'으로 게시 할 수 있습니다. 그러나 일반적으로 패키지를 설치할 때'install.packages ("data.table", dependencies = T)', 따옴표를 넣어야합니다. –

+0

나는 시험해 보았다. "고맙습니다. 아직까지는 효과가 있었지만, 다른 예에서와 같이 여러 번 긴 줄에서 여러 번 ID를 볼 수 있습니다. – stan

1

는 느낌. 출력의 열 수가 최대 요소 수인 data.frame의 요소 수와 같은 방식으로 각 벡터를 부분 집합 시키십시오. 이 최대 수 (이 예제에서는 max_length)는 각 data.frame을 나열 해제하고 lengths을 사용하여 요소 수를 얻은 다음 max을 사용하여 최대 요소 수를 얻음으로써 얻을 수 있습니다.

max_length = max(lengths(lapply(from, unlist))) 
do.call(rbind, lapply(from, function(df) 
    t(c(t(df)))[1:max_length])) 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] 
#[1,] "a" "1" "2" "3" "a" "4" " " "6" "a" "." "8" "9" 
#[2,] "b" "11" "22" "33" "b" "44" " " "66" NA NA NA NA 

UPDATE

do.call(rbind, lapply(from, function(df) 
    c(as.character(df[1,1]), t(c(t(df[,-1]))))[1:max_length])) 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] 
#[1,] "a" "1" "2" "3" "4" " " "6" "." "8" "9" NA NA 
#[2,] "b" "11" "22" "33" "44" " " "66" NA NA NA NA NA 
+0

절대적으로 그렇습니다. 그러나 IDA와 IDB를 행에서 한 번만 (시작 부분에) 생성해야합니다. 이 코드는 실제로 많은 줄을 하나로 묶어 놓았지만, 각 줄은 불행히도 새로운 줄에서 여러 번 반복합니다. 코드를 수정하는 방법? – stan

+0

@stan, 업데이트 참조 –

관련 문제