2017-03-11 1 views
0

중첩 루프를 사용하여 데이터 집합의 하위 집합을 만들려고합니다. 불행히도, 제대로 작동하지 않는 것 같습니다 : 몇 가지 경고가 발생하고 루프도 내가 원하는대로 작동하지 않습니다.R 중첩 루프 : 대체 할 항목 수가 대체 길이의 배수가 아닙니다

여기에 짧은 코드 예가 ​​나와 있습니다. 제시된 데이터는 단지 하나의 예일뿐입니다. 실제 데이터 세트는 훨씬 커졌습니다. 수동으로 값을 선택하는 것과 관련된 솔루션은 적합하지 않습니다. 내가 제한하면 자신을 내 데이터 세트에서 단지 첫 번째 요소에, "보통"(즉, 중첩 된 NOT) 루프 밖으로 작동

Warning messages: 
1: In mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == : 
    number of items to replace is not a multiple of replacement length 
2: In mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == : 
    number of items to replace is not a multiple of replacement length 
3: In mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == : 
    number of items to replace is not a multiple of replacement length 
4: In mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == : 
    number of items to replace is not a multiple of replacement length 
5: In mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == : 
    number of items to replace is not a multiple of replacement length 

:

# #If I don't use a nested loop (by just using the first element in both "mydata" and "unique_test"), things seem to work out 
# #But obviously, this is not really what I want to achieve (I can't just manually select every element in mydata and unique_test) 
mysubset <- list() 
for(i in 1:length(unique_test[[1]])){ 
    #Select myvalues whose myInter data equals the one found in unique_test and assign them to a new subset 
    mysubset[[i]] <- mydata[[1]][which(mydata[[1]]$myInter == unique_test[[1]][i]),][["myvalue"]] 
} 

# #Generate example data 
unique_test <- list() 
unique_test[[1]] <- c(178.5, 179.5, 180.5, 181.5) 
unique_test[[2]] <- c(269.5, 270.5, 271.5) 



tmp_dataframe1 <- data.frame(myID = c(268, 305, 268, 305, 268, 305, 306), 
          myvalue = c(1.150343, 2.830392, 1.150343, 2.830392, 1.150343, 2.830392, 1.150343), 
          myInter = c(178.5, 178.5, 179.5, 179.5, 180.5, 180.5, 181.5)) 

tmp_dataframe2 <- data.frame(myID = c(144, 188, 196, 300, 301, 302, 303, 97), 
          myvalue = c(1.293493, 3.286649, 1.408049, 0.469219, 11.143147, 0.687355, 0.508603, 0.654335), 
          myInter = c(269.5, 269.5, 269.5, 270.5, 270.5, 271.5, 185.5, 186.5)) 



mydata <- list() 
mydata[[1]] <- tmp_dataframe1 
mydata[[2]] <- tmp_dataframe2 
######################## 

# #Generate nested loop 
mysubset <- list() #Define list 

for(i in 1:length(unique_test)){ 
    #Prepare list of lists 
    mysubset[[i]] <- NaN 
    for(j in 1:length(unique_test[[i]])){ 
    #Select myvalues whose myInter data equals the one found in unique_test and assign them to a new subset 
    mysubset[[i]][j] <- mydata[[i]][which(mydata[[i]]$myInter == unique_test[[i]][j]),][["myvalue"]] 
    } 
} 

# #There are warnings and the nested loop is not really doing, what it is supposed to do! 

R은 다음과 같은 경고를 제공합니다

먼저 적절한 크기로 내 목록을 시작해야 할 수 있습니까? 그러나 치수가 내 데이터 집합의 모든 요소에 대해 동일하지 않으면 어떻게해야합니까 (그 이유는 처음에 length() 함수를 사용해야하는 이유입니다). mydata [[1]]은 mydata [2]와 같은 차원이 아닙니다. 다음 링크에서 제시 따라서 솔루션이 데이터 집합에 적용되지 않습니다

Error in R :Number of items to replace is not a multiple of replacement length

Error in `*tmp*`[[k]] : subscript out of bounds in R

나는 내가 부족 분명 뭔가 확신 해요,하지만 난 그냥 그것을 찾을 수 없습니다. 어떤 도움을 많이 주시면 감사하겠습니다!

루프없이 동일하게 달성하는 더 좋은 방법이 있다면 (예 : apply() 또는 subset() 행을 따라 무언가가있는 것으로 확신합니다.) 그러한 의견도 감사하겠습니다. 불행히도 나는 그들을 빨리 구현할 수있는 대안에 익숙하지 않다.

답변

1

단순히 list()에 할당 포장 : 내 이해를 바탕으로,이 unique_test의 값을 사용하여 myvalue 부분 집합한다 .

mysubset[[i]][j] <- list(mydata[[i]][which(mydata[[i]]$myInter == unique_test[[i]][j]),][["myvalue"]]) 

또는 짧은 같은 which() 필요도 외부 대괄호되지 않은 : 당신이 처음에 빈리스트를 할당하고 그것을 확장 할 필요가 없기 때문에

mysubset[[i]][j] <- list(mydata[[i]][mydata[[i]]$myInter == unique_test[[i]][j], c("myvalue")]) 
또는

는,이 솔루션을 적용 고려 반복적으로 값을 바인딩합니다. 중첩 된 lapply, sapply, mapply, 심지어 rapply은 한 번의 호출로 필요한 목록과 차원을 만들 수 있습니다. mapplyunique_test으로 가정합니다. mydata은 항상 동일한 길이의 개체입니다.

# NESTED LAPPLY 
mysubset2 <- lapply(seq(length(unique_test)), function(i) { 
    lapply(seq(length(unique_test[[i]])), function(j){ 
    mydata[[i]][mydata[[i]]$myInter == unique_test[[i]][j], c("myvalue")] 
    }) 
}) 

# NESTED SAPPLY 
mysubset3 <- sapply(seq(length(unique_test)), function(i) { 
    sapply(seq(length(unique_test[[i]])), function(j){ 
     mydata[[i]][mydata[[i]]$myInter == unique_test[[i]][j], c("myvalue")] 
    }) 
}, simplify = FALSE) 

# NESTED M/LAPPLY 
mysubset4 <- mapply(function(u, m){ 
    lapply(u, function(i) m[m$myInter == i, c("myvalue")]) 
}, unique_test, mydata, SIMPLIFY = FALSE) 

# NESTED R/LAPPLY 
mysubset5 <- rapply(unique_test, function(i){ 
    df <- do.call(rbind, mydata) 
    lapply(i, function(u) df[df$myInter == u, c("myvalue")])  
}, how="list") 

# ALL SUBSETS EQUAL EXACTLY 
all.equal(mysubset, mysubset2) 
# [1] TRUE  
all.equal(mysubset, mysubset3) 
# [1] TRUE  
all.equal(mysubset, mysubset4) 
# [1] TRUE 
all.equal(mysubset, mysubset5) 
# [1] TRUE 
+0

대단히 감사합니다. 이것으로 문제가 해결되었습니다! – user6475

0

mysubset의 모습을 게시 할 수 있습니까? 중첩 때문에 중첩 for 루프의 목록이 아닌 벡터 자체에 숫자 벡터를 할당하는 시도로

mysubset <- unique(unlist(lapply(unlist(unique_test),function(x) subset(mydata,myInter==x,select="myvalue"))))