Выполнить функцию в кадре данных через переменное число столбцов после удаления нулей - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь создать функцию, в которой я могу передать функцию в качестве переменной для выполнения с переменным числом столбцов после удаления нулей.Мне пока не очень комфортно с эллипсами, и я предполагаю, что именно здесь возникает проблема.Функция использует все значения в указанных строках, суммируя их на основе выбранной функции, а затем изменяя это одно значение.Я хотел бы сохранить функцию по всей строке (например, rowMeans)

Пример:

# Setup dataframe
a <- 1:5
b <- c(0, 4, 3, 0, 1)
c <- c(5:1)
d <- c(2, 0, 1, 0, 4)
df <- data.frame(a, b, c, d)



FUNexcludeZero <- function(function_name, ...){

  # Match function name 
  FUN <- match.fun(function_name)

  # get all the values - I'm sure this is the problem, need to somehow turn it back into a df?
  vals <- unlist(list(...))

  # Remove 0's and perform function
  valsNo0 <- vals[vals != 0]
  compiledVals <- FUN(valsNo0)
  return(compiledVals) 
}

df %>% 
  mutate(foo = FUNexcludeZero(function_name = 'sd', a, b))

  a b c d      foo
1 1 0 5 2 1.457738
2 2 4 4 0 1.457738
3 3 3 3 1 1.457738
4 4 0 2 0 1.457738
5 5 1 1 4 1.457738

df %>% 
  mutate(foo = FUNexcludeZero(function_name = 'min', a, b))

  a b c d foo
1 1 0 5 2   1
2 2 4 4 0   1
3 3 3 3 1   1
4 4 0 2 0   1
5 5 1 1 4   1

# Try row-function (same error occurs with rowMeans)
df %>% 
  mutate(foo = FUNexcludeZero(function_name = 'pmin', a, b))

Error in mutate_impl(.data, dots) : 
  Column `foo` must be length 5 (the number of rows) or one, not 8

Для function_name = 'sd' столбец должен быть c(NA, 1.41, 0, NA, 2.828) и minи pmin должно быть c(1, 2, 3, 4, 1).Я на 100% уверен, что ошибка как-то связана с list/unlist, но любой другой способ, которым я пытаюсь это сделать, приводит к ошибке.

1 Ответ

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

Я не уверен, что это именно то, что вы, что.Вам нужно было выполнить строковую операцию над двумя векторами, поэтому я использовал функцию apply.Это должно работать для любого числа векторов равной длины.

# Setup dataframe
a <- 1:5
b <- c(0, 4, 3, 0, 1)
c <- c(5:1)
d <- c(2, 0, 1, 0, 4)
#df <- data.frame(a, b, c, d) #not used

FUNexcludeZero <- function(function_name, ...){
  # Match function name 
  FUN <- match.fun(function_name)
  #combine the vectors into a matrix
  df<-cbind(...)

  #remove 0 from rows and apply function to the rows
  compiledVals <- apply(df, 1, function(x) { x<-x[x!=0] 
    FUN(x)})
  return(compiledVals) 
}

FUNexcludeZero(function_name = 'sd', a, b)
#[1]       NA 1.414214 0.000000       NA 2.828427
FUNexcludeZero(function_name = 'min', a, b)
#[1] 1 2 3 4 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...