Лучший способ применить эту функцию к каждой строке фрейма данных? - PullRequest
1 голос
/ 09 ноября 2011

Я хотел бы применить функцию к каждой строке фрейма данных, как показано ниже. Я знаю, как использовать применить в случае, когда фрейм данных содержит только числа, но что если строки содержат, скажем, логические / логические, строки и целые числа? Пример:

df <- data.frame(x=1:10,
                 y=c(TRUE, FALSE),
                 z=letters[1:10],
                 stringsAsFactors=FALSE)

RowFunction <- function(row) {
  if (row$y) return(row$x)
  return (row$z)
}

sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) })

Есть ли лучший способ сделать это? Моей первой мыслью было использовать apply(df, 1, RowFunction) после добавления row <- as.list(row) в начало RowFunction, но это не сработало, потому что применяет принуждение df к массиву, который не может обрабатывать строки, содержащие разные типы данных.

Просто для моего знания R я хотел бы знать, есть ли более чистый способ сделать это, чем sapply(1:dim(df)[1], ... ). Есть идеи?

Заранее спасибо!

Ответы [ 2 ]

6 голосов
/ 09 ноября 2011

В этом случае вы можете просто использовать ifelse:

sapply(1:dim(df)[1], function(i) { RowFunction(df[i, ]) })
 [1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j"

with(df, ifelse(y, x, z))
 [1] "1" "b" "3" "d" "5" "f" "7" "h" "9" "j"

Для удобства и читаемости я также использовал with - это позволяет ссылаться на столбец только по имени, без использования оператора $.

0 голосов
/ 09 ноября 2011

Функция ifelse может сделать это с lapply:

 lapply(df$y, ifelse, df$x, df$z)  # does return list with varying modes

Моя более ранняя (более неуклюжая) версия:

 res <- list()
 for(i in seq_along(rownames(df) ) ) { res <- c(res, df[i,1+2*!df[i,"y"] ]) }
 res
#--------
[[1]]
[1] 1

[[2]]
[1] "b"

[[3]]
[1] 3

[[4]]
[1] "d"

[[5]]
[1] 5

[[6]]
[1] "f"

[[7]]
[1] 7

[[8]]
[1] "h"

[[9]]
[1] 9

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