Вложенный оператор Ifelse в той же таблице - PullRequest
0 голосов
/ 25 августа 2018

У меня есть набор данных ниже:

Col1     Col2    Spend
   A        0      100
   A        0      100
   B        0      100
   C        0      100
   D        0      200

Я хочу написать оператор ifelse, в котором говорится, что если сумма Col2 больше 0, тогда установите Col2 = Spend. Если сумма Col2 не больше 0, тогда примените только столбец Spend к соответствующим строкам, где значение не равно A, а оставшиеся оставьте как исходные значения Col2.

Я хочу, чтобы мой окончательный результат выглядел так:

Col1     Col2    Spend
   A        0      100
   A        0      100
   B      100      100
   C      100      100
   D      200      200

Я думаю, это было бы что-то вроде этого:

df$Col2 <- ifelse(sum(df$Col2)>0, df$Spend, ifelse(df$Col1!="A", df$Spend, df$Col2))

Моя проблема в том, что когда я запускаю это, я снова проверяю сумму для Col2, и она все еще не меняется. Не уверен, что я здесь делаю не так.

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Эта проблема связана с тем, как R обрабатывает векторизованные операции, поскольку первый аргумент вашего оператора ifelse возвращает логическую длину 1 (поскольку sum(df$Col2) > 0 может возвращать только True, False или NA ), только одно из значений используется в других.

Вот пример того, что происходит

> ifelse(TRUE, 1:4, 1:4)
[1] 1
> ifelse(c(TRUE, TRUE, FALSE, FALSE), 1:4, 1:4)
[1] 1 2 3 4

Таким образом, ваш пример будет исправлен путем изменения синтаксиса как такового

if (sum(df$Col2)>0) {
    df$Col2 <- df$Spend
} else {
    df$Col2 <- ifelse(df$Col1!="A", df$Spend, df$Col2)
}

А если ДЕЙСТВИТЕЛЬНО ХОТИТЕ однострочник

df$Col2 <- ifelse(rep(sum(df$Col2)>0, nrow(df)), df$Spend, ifelse(df$Col1!="A", df$Spend, df$Col2))
0 голосов
/ 25 августа 2018

Набор данных

df = read.table(text = "
Col1     Col2    Spend
A        0      100
A        0      100
B        0      100
C        0      100
D        0      200
", header=T)

Проблема

Если вы запустите свой код, вы увидите, что он возвращает одно значение 0, которое затем реплицируется в соответствии с длиной вашего столбца. Это не возвращает пять 0 с.

ifelse(sum(df$Col2)>0, df$Spend, ifelse(df$Col1!="A", df$Spend, df$Col2))

# [1] 0

Это происходит потому, что из ?ifelse видно, что «ifelse возвращает значение той же формы, что и test ...» и ваш (test) sum(df$Col2)>0 вернет только одно значение, поскольку sum(df$Col2) - это одно значение (т.е. сумма).

Решение

Вы можете использовать оператор if ... else с вложенным ifelse следующим образом:

if (sum(df$Col2)>0) df$Spend else ifelse(df$Col1!="A", df$Spend, df$Col2)

# [1]   0   0 100 100 200

Итак, вы проверяете, что если (ваш тест) sum(df$Col2)>0 имеет значение true, то возвращает весь столбец Spend, в противном случае переходите к оператору ifelse.

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