Saya mencoba untuk membuat subset dataset saya menggunakan loop bersarang. Sayangnya, sepertinya tidak berfungsi dengan baik: Saya mendapatkan beberapa peringatan dan loop juga tidak berfungsi seperti yang saya inginkan.

Berikut contoh kode singkat. Data yang disajikan hanyalah sebuah contoh - dataset sebenarnya jauh lebih besar: Solusi apa pun yang melibatkan pengambilan nilai secara manual tidak layak dilakukan.

# #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 memberikan peringatan berikut:

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

Jika saya membatasi diri hanya pada elemen pertama dalam kumpulan data saya, loop "normal" (yaitu TIDAK bersarang) berhasil:

# #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"]]
}

Mungkinkah saya harus memulai daftar saya terlebih dahulu dengan dimensi yang sesuai? Tetapi bagaimana saya melakukannya, jika dimensinya TIDAK sama untuk semua elemen dalam dataset saya (itulah sebabnya saya harus menggunakan fungsi length() di tempat pertama)? Seperti yang Anda lihat mydata[[1]] tidak memiliki dimensi yang sama dengan mydata[[2]]. Oleh karena itu, solusi yang disajikan dalam tautan berikut tidak berlaku untuk kumpulan data ini:

Kesalahan di R :Jumlah item yang akan diganti bukan kelipatan dari panjang penggantian

Kesalahan dalam `*tmp*`[[k]] : subskrip di luar batas dalam R

Saya cukup yakin itu adalah sesuatu yang jelas saya lewatkan, tetapi saya tidak dapat menemukannya. Bantuan apa pun sangat dihargai!

Jika ada cara yang lebih baik untuk mencapai hal yang sama tanpa loop (saya yakin ada, misalnya apply() atau sesuatu di sepanjang baris subset()), saya akan menghargai komentar seperti itu juga. Sayangnya saya tidak cukup akrab dengan alternatif untuk dapat mengimplementasikannya dengan cepat.

0
user6475 12 Maret 2017, 02:36

2 jawaban

Jawaban Terbaik

Cukup bungkus tugas Anda dalam list() saat Anda mencoba menetapkan vektor numerik ke daftar bersarang karena loop for bersarang dan bukan vektor itu sendiri.

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

Atau yang lebih pendek sebagai which() tidak diperlukan atau tanda kurung siku luar:

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

Atau, pertimbangkan solusi apply karena pada awalnya Anda tidak perlu menetapkan daftar kosong dan memperluasnya secara iteratif untuk mengikat nilai ke dalamnya. Bersarang lapply, sapply, mapply, bahkan rapply dapat membuat daftar dan dimensi yang diperlukan dalam satu panggilan. mapply mengasumsikan unique_test dan mydata selalu merupakan objek yang panjangnya sama.

# 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
1
Parfait 12 Maret 2017, 03:34

Bisakah Anda memposting seperti apa tampilan subset saya? Berdasarkan pemahaman saya, ini harus mengelompokkan nilai saya menggunakan nilai dalam unique_test:

mysubset <- unique(unlist(lapply(unlist(unique_test),function(x) subset(mydata,myInter==x,select="myvalue"))))
0
Naresh Pai 12 Maret 2017, 00:23