a <- c(0, 0, 1, 1, 0, 0, 0, 1, 0, 0) のような 0/1 要素からなるベクトルの連続する 0 を 1 個の 0 に縮小するというプログラム。
x <- with(rle(a), rep(values, ifelse(values == 1, lengths, 1)))
という回答があった。それを書き換えて
b <- rle(a); b$lengths[!b$values] <- 1; y <- inverse.rle(b)
とすると速度は倍になる。
z <- as.integer(unlist(strsplit(gsub("0+", "0", paste(a, collapse="")), "")))
は速度が半分になる。
以下では warning が出る。結果は正しいのだが。
> temp <- c("123", NA, "-", "---")
> ifelse(!(is.na(temp) | !grepl("-*[0-9]+.*[0-9]*", temp)), as.numeric(temp), NA)
ifelse(!(is.na(temp) | !grepl("-*[0-9]+.*[0-9]*", temp)), as.numeric(temp), 中で警告がありました:
強制変換により NA が生成されました
[1] 123 NA NA NA
以下のようにすると warning は出なくなる。
> as.numeric(ifelse(!is.na(temp) & grepl("-*[0-9]+.*[0-9]*", temp), temp, NA))
[1] 123 NA NA NA
以下の例を見れば明らかであるが,ifelse では第1引数(論理演算式)の評価結果に関わらず,第2,第3引数が評価されてしまう。注意しなければ。
> x <- c(-2:3)
> sqrt(x)
[1] NaN NaN 0.000000 1.000000 1.414214 1.732051
警告メッセージ:
In sqrt(x) : 計算結果が NaN になりました
> ifelse(x >= 0, sqrt(x), NA)
[1] NA NA 0.000000 1.000000 1.414214 1.732051
警告メッセージ:
In sqrt(x) : 計算結果が NaN になりました
> sqrt(ifelse(x >= 0, x, NA)) このようにすべし
[1] NA NA 0.000000 1.000000 1.414214 1.732051