data.table ifelse с несколькими столбцами - PullRequest
1 голос
/ 23 января 2020

У меня есть набор данных с десятками столбцов, который выглядит примерно так:

df <- data.frame(id= c(1,1,1,2,2,2,3,3,3), time=c(1,2,3,1,2,3,1,2,3),y1 = rnorm(9), y2= rnorm(9), x = rnorm(9), xb = rnorm(9))
df
#   id time      y1          y2           x          xb
# 1  1    1 -1.1184009 -1.07430118  0.61398523 -0.68343624
# 2  1    2  0.4347047 -0.53454071 -0.30716538 -1.02328242
# 3  1    3  0.2318315 -0.05854228  0.05169733 -0.22130149
# 4  2    1  1.2640080  2.07899296 -0.95918953 -0.35961156
# 5  2    2 -0.4374764 -0.25284854 -0.46251901  0.08630344
# 6  2    3  0.5042690  0.13322671  1.00881113  0.43807458
# 7  3    1  0.3672216  1.92995242  0.48708183  0.58206127
# 8  3    2 -1.5431709  0.53362731  1.17361087 -1.00932195
# 9  3    3 -1.4577268  0.23413541 -0.32399489 -0.91040641

Я хотел бы изменить свой фрейм данных, используя следующую логику c

df<-setDT(df)[,y1:=ifelse(y1>x,x,y1))]
df<-setDT(df)[,y2:=ifelse(y2>xb,xb,y2))]

Тем не менее, поскольку у меня много переменных, я хотел бы сделать это в выражении в одну строку. Другими словами, я хотел бы передать эту функцию для нескольких столбцов одновременно, т.е. y1 с x, y2 с xb и т. Д. Я пробовал следующее, но, похоже, не работает

mod<-c("y1","y2")
max<-c("x","xb")
df2<-setDT(ppta)[,(mod):=ifelse(.(mod)>.(max),.(max),.(mod))]

кто-нибудь знает, что я делаю не так? и как я могу изменить несколько столбцов с соответствующим партнерским столбцом одновременно?

1 Ответ

3 голосов
/ 23 января 2020

Попробуйте использовать pmin вместо ifelse. Вы можете попробовать:

mod<-c("y1","y2")
max<-c("x","xb")
setDT(df)    
df[,c(mod):=Map(pmin,mget(mod),mget(max))]

Объяснение:

  • pmin принимает два (или более) вектора и дает минимальное значение для каждого элемента (эквивалент вашего ifelse(y1>x,x,y1)) ;
  • mget возвращает список объектов по их именам. Например, mget("a","b") возвращает список с объектами a и b (если они существуют). Это используется для извлечения столбца из их имени в среде таблицы данных;
  • Map применяет функцию с большим количеством аргументов элемент за элементом. Map(f,a,b) эквивалентно list(f(a[[1]],b[[1]]),f(a[[2]],b[[2]]),...).
...