Вычесть два столбца в фрейме данных, если выполняется условие

Мой фрейм данных:

Dead4   Dead5
0       0
0       0
0       0
1       2
0       0
0       0
1       2
0       0
1       0
0       1
1       1
5      10

Я хочу, чтобы мой код говорил всякий раз, когда Dead5 больше Dead4 в той же строке, вычтите два значения и поместите это значение в Dead5

indices<- (t$Dead5 > t$Dead4) 
t$Dead6[indices]<- (t$Dead6) - (t$Dead5)


Warning message:
In t$Dead6[indices] <- (t$Dead6) - (t$Dead5) :
  number of items to replace is not a multiple of replacement length

Могут ли некоторые объяснить, что я делаю неправильно, и помочь мне написать несколько строк кода, которые это сделают?

4 ответа

Решение

Вы можете сделать это:

indices <- (t$Dead5 > t$Dead4) # indices is a logical vector with TRUE and FALSE

t$Dead5[indices] <- (t$Dead5 - t$Dead4)[indices]

Это также относится к любой другой операции с вашим data.frame, например:

t$Dead6[indices] <- (t$Dead6 - t$Dead5)[indices]

Если столбец Dead6 существует. На каждой стороне только значения где indices является TRUE взяты, поэтому значения замены и замены имеют одинаковую длину, и вы не получите предупреждение.

То, что вы делали неправильно, вы давали в качестве замены полной (t$Dead5 - t$Dead4) вектор, который больше, чем число раз indices является TRUE (замененные значения слева).

R использовал только первые значения вашего вектора замены и выдавал вам предупреждение.

С помощью transform() а также ifelse():

transform(t, Dead5 = ifelse(Dead5 > Dead4, Dead5-Dead4, Dead5))

С помощью data.table

library(data.table)
DT <- as.data.table(DF)

DT[Dead5 > Dead4, Dead5 := Dead5 - Dead4]

Вы также можете сделать это в base R с помощью within или же transform

Другой подход без ifelse и без индексации:

indices <- t$Dead5 > t$Dead4 
t$Dead6 <- t$Dead6 - (t$Dead5 * indices)
Другие вопросы по тегам