R: Умножьте каждый элемент <1 в списке на 10, пока элемент не станет> 1 - PullRequest
3 голосов
/ 30 апреля 2020

x - это вектор двойной точности, содержащий числа, меньшие и большие чем 1:

x <- c(1, 2, 3, 0.1, 0.02, 0.003)

Если элемент в x меньше единицы, я хотел бы умножить этот элемент на 10, пока он не станет больше чем один; если элемент уже больше единицы, он должен остаться без изменений. Результатом должен быть вектор с двойной точностью:

(1, 2, 3, 1, 2, 3)

Мне кажется, это должно быть очень просто, но решение ускользает от меня. Вот что я сделал до сих пор. Я определил функцию times_ten, которая выполняет описанную выше операцию:

times_ten <- function(x) {
  while (x < 1) {
    x <- x * 10
  }
}

Затем я применяю эту функцию к вектору x:

y <- sapply(c(1, 2, 3, 0.1, 0.02, 0.003), function(x) times_ten(x))

Но теперь y - это список, а не a удвоится. Хуже того, все значения в y теперь равны NULL.

Нужно ли менять функцию, и если да, то как? Или есть лучший подход полностью?

Ответы [ 2 ]

4 голосов
/ 30 апреля 2020

Как сказал @ Neel , вам нужно return(x) в конце вашей функции times_ten.


Ниже приведен более простой способ преобразования, где log10() был использован

y <- x*10**ifelse(-log10(x)>=1,ceiling(-log10(x)),0)

такой, что

> y
[1] 1 2 3 1 2 3
2 голосов
/ 30 апреля 2020

Полагаю, вы пропустили return утверждение в своей функции.

times_ten <- function(x){
      while (x < 1) {
        x <- x * 10
      }
      return(x)
    }

, с этим ваше решение совершенно верно.

y <- sapply(c(1, 2, 3, 0.1, 0.02, 0.003), function(x) times_ten(x))

Вот еще одно решение.

library(tidyverse)
x %>% map_dbl(~times_ten(.x))

дает мне вывод как

[1] 1 2 3 1 2 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...