2016-01-18 5 views
0

У меня есть следующий фрагмент данных:Как пропустить ошибку в цикле, сохраняя недостающий элемент как пустой столбец?

> dput(data) 
structure(c(0.640372781, 0.54596394, 0.364612178, 0.554321638, 
0.623891566, 0.299900389, 0.629781465, 0.502673674, 0.414942748, 
0.485381455, 0.629032253, 0.201974626, 0.549820206, 0.49277897, 
0.299640651, 0.443151949, 0.506297992, 0.259198111, 0.635090505, 
0.597640686, 0.430193856, 0.631067648, 0.662995875, 0.391062922, 
0.632248042, 0.627503454, 0.432827825, 0.418849204, 0.612201188, 
0.227470395, 0.556520484, 0.6095603, 0.414923451, 0.57634896, 
0.543780581, 0.320027087, 0.655818488, 0.648937123, 0.497094053, 
0.429772696, 0.632386262, 0.270060224, 0.564427852, 0.456642259, 
0.492407708, 0.436349654, 0.616355794, 0.248897538, 0.642866477, 
0.555022037, 0.358901689, 0.53184597, 0.606299729, 0.342449093, 
0.667681177, 0.506448197, 0.370292817, 0.555462276, 0.642302168, 
0.42487856, 0.649249462, 0.544035494, 0.394793334, 0.383522657, 
0.557789563, 0.220189788, 0.636151283, 0.547825201, 0.391789202, 
0.653913292, 0.649412792, 0.452257495, 0.648866884, 0.535907987, 
0.392093314, 0.724788138, 0.674157973, 0.494385979, 0.673032345, 
0.450686601, 0.369089571, 0.397124065, 0.502592807, 0.197922003 
), class = c("xts", "zoo"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC", index = structure(c(1025049600, 
1025136000, 1025222400, 1025481600, 1025568000, 1025654400), tzone = "UTC", tclass = "Date"), .Dim = c(6L, 
14L), .Dimnames = list(NULL, c("AN8068571086", "BMG3223R1088", 
"BMG4388N1065", "BMG6359F1032", "BMG7496G1033", "BMG812761002", 
"CA88157K1012", "CH0044328745", "CH0048265513", "GB00B4VLR192", 
"GB00B5BT0K07", "GB00B6SLMV12", "GB00BFG3KF26", "GB00BVVBC028" 
))) 

И этот код:

######## INPUTS ###### 

a <- 0.5 
b <- 0.6 

results <- list() # list containing loop results 

####################### 


for (i in 1:nrow(data)) { 


    input <- as.matrix(data[i,]) 

    #extract column names with a value between a and b 

    stocks <- matrix(colnames(data[,which(input > a & input < b)])) 

    # make a vector with new name for the output 
    date <- head(rownames(input), n=1) 

    #rename column 
    colnames(stocks) <- date 

    #export to list under "date" name 
    results[[date]] <- stocks 

} 

Если вы запускаете его точно так, как это вы получите эту ошибку:

Error in matrix(colnames(data[, which(input > a & input < b)])) : 
    'data' must be of a vector type, was 'NULL' 
In addition: Warning messages: 
1: In min(j, na.rm = TRUE) : 
    no non-missing arguments to min; returning Inf 
2: In max(j, na.rm = TRUE) : 
    no non-missing arguments to max; returning -Inf 

Это поступает из третьего ряда в data, который не содержит значений между 0,5 и 0,6

matrix(colnames(data[,which(input > a & input < b)])) 

После выполнения кода я запускаю это, который объединяет все мои данные вместе и готовит его для других расчетов:

# merge all results in a list 
max_length <- max(sapply(results ,length)) 

final_results <- sapply(results, function(x){ 
    c(x, rep(NA, max_length - length(x))) 
}) 

я нужен способ, чтобы пропустить эту ошибку, сохраняя название даты как пустой столбец в final_results. Я думаю, может быть, функция if такая, что если нет значений, которые лежат между a и b, пустая матрица (1x1) создается с помощью colname = date, которая должна храниться в списке results.

другой вариант будет использовать tryCatch, но это будет опускать дату целиком и между тысячами, которые у меня здесь, будет невозможно найти недостающие столбцы.

ответ

2

Если вы используете функцию tryCatch, которая обрабатывает вашу ошибку, возвращая матрицу с значением NA, вы получите столбец с соответствующей датой в качестве имени, содержащего только NA в вашем final_results. Однако это будет обрабатывать все ошибки одинаково, поэтому не может быть лучшим решением, если ваши данные могут вызывать разные ошибки.

stocks <- tryCatch(matrix(colnames(data[,which(input > a & input < b)])), 
         error = function(e) matrix(NA)) 
+0

Не знал, что вы можете использовать trycatch таким образом. Спасибо –

2

Быстрое решение для вашей задачи:

DF <- as.data.frame(data) 
DF <- apply(DF, 1, function(x) { 
    ifelse(x > a & x < b, x, NA_real_) 
}) 

Результат этого:

> DF 
      2002-06-26 2002-06-27 2002-06-28 2002-07-01 2002-07-02 2002-07-03 
AN8068571086   NA 0.5459639   NA 0.5543216   NA   NA 
BMG3223R1088   NA 0.5026737   NA   NA   NA   NA 
BMG4388N1065 0.5498202   NA   NA   NA 0.5062980   NA 
BMG6359F1032   NA 0.5976407   NA   NA   NA   NA 
BMG7496G1033   NA   NA   NA   NA   NA   NA 
BMG812761002 0.5565205   NA   NA 0.5763490 0.5437806   NA 
CA88157K1012   NA   NA   NA   NA   NA   NA 
CH0044328745 0.5644279   NA   NA   NA   NA   NA 
CH0048265513   NA 0.5550220   NA 0.5318460   NA   NA 
GB00B4VLR192   NA 0.5064482   NA 0.5554623   NA   NA 
GB00B5BT0K07   NA 0.5440355   NA   NA 0.5577896   NA 
GB00B6SLMV12   NA 0.5478252   NA   NA   NA   NA 
GB00BFG3KF26   NA 0.5359080   NA   NA   NA   NA 
GB00BVVBC028   NA   NA   NA   NA 0.5025928   NA 

Если вы хотите отказаться от столбцов, которые все NA сек, то вы можете фильтровать их например:

DF <- DF[ 
    , apply(DF, 2, function(x) { 
    sum(is.na(x)) != length(x) 
})] 

Результат после фильтрации:

> DF 
      2002-06-26 2002-06-27 2002-07-01 2002-07-02 
AN8068571086   NA 0.5459639 0.5543216   NA 
BMG3223R1088   NA 0.5026737   NA   NA 
BMG4388N1065 0.5498202   NA   NA 0.5062980 
BMG6359F1032   NA 0.5976407   NA   NA 
BMG7496G1033   NA   NA   NA   NA 
BMG812761002 0.5565205   NA 0.5763490 0.5437806 
CA88157K1012   NA   NA   NA   NA 
CH0044328745 0.5644279   NA   NA   NA 
CH0048265513   NA 0.5550220 0.5318460   NA 
GB00B4VLR192   NA 0.5064482 0.5554623   NA 
GB00B5BT0K07   NA 0.5440355   NA 0.5577896 
GB00B6SLMV12   NA 0.5478252   NA   NA 
GB00BFG3KF26   NA 0.5359080   NA   NA 
GB00BVVBC028   NA   NA   NA 0.5025928 
+0

@Alex Bădoi: Это имеет смысл для вас? –