Первая проблема
test = df %>% mutate_if(is.numeric, ~./sum(.))
test %>% select_if(is.numeric) %>% colSums( ,na.rm = T)
test = df %>% mutate_if(is.numeric, function(x) x/sum(x))
test %>% select_if(is.numeric) %>% colSums()
Вы можете справиться со своей проблемой, указав na.rm = T
так, чтобы не сохранять NA
. Они происходят, потому что вы делите на 0. Это то же самое для второго синтаксиса, который делает то же самое. mutate_if
применить для каждого числового столбца требуемую операцию, поэтому для третьего столбца он возвращает Nan из-за 0.
Вторая проблема
test = df %>% mutate_if(is.numeric, function(x){ifelse(x > 0, x/sum(x), rep(0, length(x)))})
test %>% select_if(is.numeric) %>% colSums()
test = df %>% mutate_if(is.numeric, function(x) ifelse(sum(x)>0, x/sum(x), 0))
test %>% select_if(is.numeric) %>% colSums()
ifelse возвращает значение с той же формой, что и для тестатак что в вашем случае, поскольку вы проверяете «sum (x)> 0», вы возвращаете только первое значение. См .:
https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/ifelse
Третья проблема
test = df %>% mutate_if(is.numeric, ~apply(., 2, function(x) x/sum(x)))
Здесь сложно, mutate_if применяется к вектору, и вы хотите использовать apply затем, но ваш объект являетсяvector и apply корректны только для таких объектов, как matrix
или data.frame
, как минимум с двумя столбцами.
Один хороший ответ
test = df %>% mutate_if(is.numeric, function(x) if(sum(x)>0) x/sum(x))
test %>% select_if(is.numeric) %>% colSums()
Действительно, это правильный синтаксис, поскольку if
не требует возврата объекта определенного размера.
Однако вы также можетеиспользуйте ifelse
, но с векторным условием действительно сумма положительных значений не равна нулю, если хотя бы один элемент отличается от 0.
test = df %>% mutate_if(is.numeric, function(x){ifelse(x > 0, x/sum(x), rep(0, length(x)))})
test %>% select_if(is.numeric) %>% colSums()
Надеюсь, это поможет вам понять, что происходит, когдапоявляется ошибкаРешение не уникальное.
Редактировать 1:
Причина в том, что вы возвращаете что-то, только если ваша сумма строго больше 0. Вы должны указать, что делать, если нет. Вот так например:
test = df %>% mutate_if(is.numeric, function(x) if(sum(x)>0){x/sum(x)}else{0})