【问题标题】:data.table ifelse with multiple columns具有多列的 data.table ifelse
【发布时间】:2020-01-23 15:59:21
【问题描述】:

我有一个包含数十列的数据集,看起来像这样:

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

我想使用以下逻辑修改我的数据框

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

但是,由于我有很多变量,我想在单行表达式中执行此操作。换句话说,我想一次将这个函数传递给多个列,即y1xy2xb 等等...... 我尝试了以下方法,但它似乎不起作用

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

有谁知道我做错了什么?以及如何一次修改多个列及其各自的合作伙伴列?

【问题讨论】:

  • 它应该是什么意思?对于比较部分,这是否意味着任何 mod 列都大于任何 max 列?还是应该是所有列对所有列的比较?
  • 准确地说,我希望每次mod 中的列的值高于max 中的相应列时,mod 列将其值更改为max

标签: r data.table data-manipulation


【解决方案1】:

考虑使用pmin 而不是您的ifelse。你可以试试:

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

解释:

  • pmin 接受两个(或更多)向量并给出每个元素的最小值(相当于您的 ifelse(y1&gt;x,x,y1));
  • mget 根据名称返回对象列表。例如mget("a","b") 返回一个包含ab 对象的列表(如果它们存在)。这用于在数据表的环境中从它们的名称中检索列;
  • Map 逐个元素地应用具有更多参数的函数。 Map(f,a,b) 等价于 list(f(a[[1]],b[[1]]),f(a[[2]],b[[2]]),...)

【讨论】:

  • 这似乎可以完成这项工作,您介意再解释一下该函数的逻辑是什么吗?我不知道Map函数
猜你喜欢
  • 2013-07-19
  • 2019-08-03
  • 2017-10-01
  • 1970-01-01
  • 2016-10-13
  • 2017-03-11
  • 2019-10-27
  • 2018-06-24
  • 1970-01-01
相关资源
最近更新 更多