2015-06-17 1 views
1

Я хочу пропустить кадр данных и создать новый столбец с надписью «YES», если 2-й элемент в строке «ANOMALY 'и' НЕТ 'в противном случае.пытаясь векторизовать эту операцию в R, и я не понимаю, почему это неверно

for (j in 1:nrow(residual_anomalies)){ 
    if (all(residual_anomalies[j,2:4]=='ANOMALY')) {residual_anomalies$Prediction_Anomaly[j] <- 'YES'} else 
    residual_anomalies$Prediction_Anomaly[j] <- 'NO' 
} 

Так что в настоящее время это то, что я использую. Он работает, но он принимает большой вычислительный показатель производительности, поэтому я пытаюсь его векторизовать. То, что я делал до сих пор, это создать функцию, которая возвращает «ДА» или «НЕТ» на основе, если элементы строки были «ANOMALY».

vote_for_anomaly <- function(x){ 
    if (all(x)=='ANOMALY') return('YES') else 
    return('NO')} 

И тогда я пытаюсь использовать функцию применения в R

aggregates <- apply(residual_anomalies[,2:4],1,vote_for_anomaly) 

, но затем я получаю следующие ошибки/предупреждения

Error in if (all(x) == "ANOMALY") return("ANOMALY") else return("NO SIGNAL") : 
    missing value where TRUE/FALSE needed 
In addition: Warning message: 
In all(x) : coercing argument of type 'character' to logical 

Может кто-нибудь сказать мне, почему это ISN Я работаю и как мне это изменить?

Вы можете использовать эти данные для тестирования и назвать его residual_anomalies

1  ANOMALY  ANOMALY  ANOMALY  ANOMALY 
2  ANOMALY  NO SIGNAL  ANOMALY  ANOMALY 
3  ANOMALY  ANOMALY  ANOMALY  ANOMALY 
4  NO SIGNAL  ANOMALY  NO SIGNAL  ANOMALY 
5  ANOMALY  ANOMALY  ANOMALY  ANOMALY 
6  NO SIGNAL  NO SIGNAL  ANOMALY  ANOMALY 
+1

Может быть 'if (all (x == 'ANOMALY')) ...'? – lukeA

+0

Ничего себе! Я не могу поверить, что это было нечто незначительное ... спасибо! – Glassjawed

ответ

0

Per @lukeA, есть опечатка в коде. Он должен быть

all(x == "ANOMALY") 

но было бы быстрее сделать:

residual_anomalies$Prediction_Anomaly <- 
    ifelse(rowSums(residual_anomalies[, 2:4] == "ANOMALY") == 3, "YES", "NO") 

rowSums очень быстро.

0

Как сказал @lukeA вы перепутали свои круглые скобки, но здесь это проще по всему решению, а также:

aggregates <- ifelse(apply(residual_anomalies, 1, 
    function(x) all(x[2:4] == "ANOMALY")), "YES", "NO") 
1

Это может быть быстрее, чтобы сделать это с помощью индексации, а не ifelse(). Сначала создать вектор No требуемой длины:

aggregates <- rep("No", NROW(residual_anomalies)) 

Тогда просто указательным этот вектор, где все residual_anomalies[, 2:4] == "ANOMALY"

aggregates[rowSums(residual_anomalies[, 2:4] == "ANOMALY") == 3L] <- "Yes" 

Это дает:

> aggregates 
[1] "Yes" "No" "Yes" "No" "Yes" "No" 

Эта часть residual_anomalies[, 2:4] == "ANOMALY" создает логическую матрицу :

> residual_anomalies[, 2:4] == "ANOMALY" 
     V2 V3 V4 
[1,] TRUE TRUE TRUE 
[2,] FALSE TRUE TRUE 
[3,] TRUE TRUE TRUE 
[4,] TRUE FALSE TRUE 
[5,] TRUE TRUE TRUE 
[6,] FALSE TRUE TRUE 

Когда мы берем rowsums(), TRUE преобразуется в 1 и FALSE - 0. Следовательно, будут выбраны только те строки, в которых все элементы равны TRUE, и назначаются "Yes".

Смежные вопросы