Примените функцию к каждому столбцу data.frame и организуйте вывод - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть этот вектор:

 x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11)

Я использую эту функцию:

myfunction <- function(x){
     n <- length(x)
     fx <- numeric(n)
     fx[1] <- min(x[1],0)
     for(i in 2:n){fx[i] <- min(0,fx[i-1]+x[i])}
     fx

     x_min <-min(x)
     fx_min <- min(fx)

     fx_05 <- numeric(n)
     fx_05[1] <- min(fx[1],0)
     for (i in 2:n) {
       if (sum(fx_05[i-1]+x[i])>0) {  
          fx_05[i] <- 0
       } else if ((sum(fx_05[i-1]+x[i]))<(fx_min*0.5)) {
          fx_05[i] <- (fx_min*0.5)
       } else { fx_05[i] <- sum(fx_05[i-1]+x[i]) }
     }
     fx_05
     as.data.frame(matrix(c(x, fx_05), ncol = 2 ))
}
xx <- myfunction(x)

Кадр данных xx равен

    V1   V2
1    5  0.0
2    2  0.0
3   -4 -4.0
4   -6 -8.5
5   -2 -8.s
6    1 -7.5
7    4 -3.5
8    2 -1.5
9   -3 -4.5
10  -6 -8.5
11  -1 -8.5
12   8 -0.5
13   9  0.0
14   5  0.0
15  -6 -6.0
16 -11 -8.5`

Я хотел быприменить эту функцию к data.frame:

df <- data.frame(x <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                   y <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11),
                   z <- c(5,2,-4,-6,-2,1,4,2,-3,-6,-1,8,9,5,-6,-11))

Использование:

output <- myfunction(df) 

Это не работает, и использование:

outputs <- data.frame(sapply(df, myfunction))

в формевывод data.frame неверен.Должно быть 2 столбца для каждого исходного столбца data.frame.

1 Ответ

0 голосов
/ 07 декабря 2018

В этом случае вы хотели бы использовать lapply.Он будет обрабатывать каждый столбец data.frame, поскольку на самом деле это список векторов равной длины, и каждый из двух столбцов будет возвращать data.frame.

x <- lapply(df, myfunction)

Кроме того, sapply работает просто отлично.Разница лишь в том, что в начале все выглядит иначе.См. print(x) разницу между всеми решениями.

x <- sapply(df, myfunction)

После этого вы, вероятно, захотите снова объединить их из списка в data.frame.Вы можете сделать это с помощью do.call

df2 <- do.call(cbind, x)

Это приведет к путанице в именах столбцов.Вы можете изменить их, используя names

names(df2) <- NULL
df2
# 1    5  0.0   5  0.0   5  0.0
# 2    2  0.0   2  0.0   2  0.0
# 3   -4 -4.0  -4 -4.0  -4 -4.0
# 4   -6 -8.5  -6 -8.5  -6 -8.5
# ....

. Примечание:

Если у вас нет data.frame, но в качестве входной матрицы, другой вариант будет apply сс MARGIN = 2.

x <- apply(df, MARGIN = 2, myfunction)

Несмотря на то, что в этом примере это также работает, вы столкнетесь с проблемами при наличии разных типов данных по вашим векторам, поскольку он преобразует data.frame в матрицу перед применением функции.Поэтому это не рекомендуется.Более подробную информацию об этом можно найти в этом подробном и простом для понимания посте !

Дальнейшее прочтение по этому вопросу:
Advanced R Хэдли Уикхэма.Также ознакомьтесь с разделом о типах данных на этом сайте.
Сообщение в блоге Питера Вернера


Я очень благодарен за ввод @ Gregor для этогосообщение.

...