Округление числа с плавающей точкой до ближайшего целого числа в пределах отсечения расстояния - PullRequest
1 голос
/ 08 февраля 2020

У меня есть data.frame с одним столбцом, в котором указаны идентификаторы, и несколькими другими, которые имеют числовые значения. В каждом из этих столбцов числовых значений есть целые и дробные числа:

set.seed(1)
df <- data.frame(id = paste0("id_",sample(LETTERS,100,replace=T)),
                 var_1 = c(as.integer(runif(80,0,3)),runif(20,0,2))[permute::shuffle(100)],
                 var_2 = c(as.integer(runif(90,0,3)),runif(10,0,2))[permute::shuffle(100)],
                 var_3 = c(as.integer(runif(70,0,3)),runif(30,0,2))[permute::shuffle(100)])

Я ищу быстрое function, которое будет округлять каждое число с плавающей точкой в ​​каждом числовом столбце до ближайшее целое число, если это расстояние меньше 0,1, в противном случае преобразуйте его в NA.

Прямо сейчас у меня есть это:

df[,-1] <- do.call(cbind,lapply(colnames(df)[-1], function(i){
  dists <- ceiling(df[,i])-df[,i]
  idx <- which(dists > 0.5)
  if(length(idx) > 0) dists[idx] <- dists[idx]-1
  idx <- which(abs(dists) > 0.1)
  if(length(idx) > 0) dists[idx] <- NA
  return(df[,i]+dists)
}))

Но интересно, есть ли что-нибудь более быстрое / более элегантное?

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Возможно, чуть-чуть быстрее и компактнее:

df[,-1][abs(round(df[,-1]) - df[,-1]) >.1] <- NA
df <- data.frame(id=df[,1], round(df[,-1]))
1 голос
/ 08 февраля 2020

Это также можно сделать без всего oop, создав логическое matrix

dists <- ceiling(df[-1]) - df[-1]
i1 <- dists  > 0.5
dists[i1] <- dists[i1] -1
i2 <- abs(dists) > 0.1
dists[i2] <- NA
df[-1] <- df[-1] + dists
...