为数据表(R)中的每一行获取最后1的索引
我目前正在尝试适应为数据表(R)中的每一行获取最后1的索引,r,data.table,R,Data.table,我目前正在尝试适应R中的data.table包。我想获取数据表每行中最后一个1的索引,比如a,然后将新列添加到a。我的代码如下: a = data.table(matrix(sample(c(0,1),500,rep=T),50,10)) a[,ind:=apply(a==1,1,function(x) max(which(x)))] 尽管如此,我认为这可以通过使用更多的data.table语法以一种简单的方式编写。因此,我的问题是:如果j组件中没有apply函数,如何实现这一点[?好
R
中的data.table
包。我想获取数据表每行中最后一个1
的索引,比如a
,然后将新列添加到a
。我的代码如下:
a = data.table(matrix(sample(c(0,1),500,rep=T),50,10))
a[,ind:=apply(a==1,1,function(x) max(which(x)))]
尽管如此,我认为这可以通过使用更多的
data.table
语法以一种简单的方式编写。因此,我的问题是:如果j
组件中没有apply
函数,如何实现这一点[?好问题。是的,按行应用
没有页面效率,将为每一行分配,而a==1
创建一个与a
一样大的新逻辑矩阵
在data.table
中,我们按列进行操作。有时,对于data.table
-ish,使用循环遍历列(从不循环遍历行):
正如你所看到的,这是一种完全不同的风格。但是,我认为,这应该是:
- 页面效率高;即,它通过内存中连续的列运行
- 需要一列(仅)大的工作内存,而不是整个
a
- 调用
which()
不过,我没有做任何速度测试,所以我可能不得不收回我的话
请参见设置
作为对注释的响应,为了检查它是如何工作的,set
恰好返回一个指向data.table
的指针,因此我们可以在它运行时查看前几行
a[,ans:=0L] # add column by reference, initialized with 0L
> head(a)
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 0
2: 0 0 1 1 0 0 1 1 1 1 0
3: 0 1 0 0 0 1 1 1 1 0 0
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 0
6: 1 1 0 1 1 0 1 0 1 1 0
现在,希望以下内容能够揭示它的工作原理:
> for (i in 1:10) print(head(set(a,which(a[[i]]==1),"ans",i)))
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 0
2: 0 0 1 1 0 0 1 1 1 1 0
3: 0 1 0 0 0 1 1 1 1 0 0
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 1
6: 1 1 0 1 1 0 1 0 1 1 1
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 0
2: 0 0 1 1 0 0 1 1 1 1 0
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 2
6: 1 1 0 1 1 0 1 0 1 1 2
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 3
2: 0 0 1 1 0 0 1 1 1 1 3
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 3
6: 1 1 0 1 1 0 1 0 1 1 2
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 3
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 4
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 4
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 5
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 5
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 5
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 6
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 6
4: 0 0 0 1 1 0 1 1 1 1 5
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 5
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 6
2: 0 0 1 1 0 0 1 1 1 1 7
3: 0 1 0 0 0 1 1 1 1 0 7
4: 0 0 0 1 1 0 1 1 1 1 7
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 7
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 8
2: 0 0 1 1 0 0 1 1 1 1 8
3: 0 1 0 0 0 1 1 1 1 0 8
4: 0 0 0 1 1 0 1 1 1 1 8
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 7
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 9
2: 0 0 1 1 0 0 1 1 1 1 9
3: 0 1 0 0 0 1 1 1 1 0 9
4: 0 0 0 1 1 0 1 1 1 1 9
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 9
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 10
2: 0 0 1 1 0 0 1 1 1 1 10
3: 0 1 0 0 0 1 1 1 1 0 9
4: 0 0 0 1 1 0 1 1 1 1 10
5: 1 1 1 1 0 0 0 0 0 1 10
6: 1 1 0 1 1 0 1 0 1 1 10
>
你对这个问题的解决方案很好(如果它是按照我的想法做的话),尽管它与我使用的有很大的不同。你能解释一下它在做什么吗set(a,它(a[[I]]==1),“foo”,I)?感谢@Matthew Dowle!@Nestorghh添加了edit,hth。有关set
参数的解释,请参见?set
。感谢你的解释@Matthew Dowle。这就是我们认为它正在做的。当然,这是一种不同的风格。另一方面,我们用巨大的数据表进行了一些实验,差异非常明显le.我们尝试了一个2000000行的数据表,您的set
解决方案比我们的apply
方法快53倍。除了?set
,您能告诉我是否还有其他参考资料来阅读有关set
函数的更多信息吗?谢谢!感谢更新,很高兴它能工作。如果您还有其他问题,请联系我们答案不是?set
请让我知道,这样它可以改进。我唯一能想到的是搜索,它的示例非常详细(set
是在v1.8.0中添加的)。a[,ind:=max.col(.SD==1,“last”)]
可能会更快
> for (i in 1:10) print(head(set(a,which(a[[i]]==1),"ans",i)))
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 0
2: 0 0 1 1 0 0 1 1 1 1 0
3: 0 1 0 0 0 1 1 1 1 0 0
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 1
6: 1 1 0 1 1 0 1 0 1 1 1
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 0
2: 0 0 1 1 0 0 1 1 1 1 0
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 2
6: 1 1 0 1 1 0 1 0 1 1 2
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 3
2: 0 0 1 1 0 0 1 1 1 1 3
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 0
5: 1 1 1 1 0 0 0 0 0 1 3
6: 1 1 0 1 1 0 1 0 1 1 2
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 3
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 4
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 4
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 5
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 2
4: 0 0 0 1 1 0 1 1 1 1 5
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 5
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 6
2: 0 0 1 1 0 0 1 1 1 1 4
3: 0 1 0 0 0 1 1 1 1 0 6
4: 0 0 0 1 1 0 1 1 1 1 5
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 5
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 6
2: 0 0 1 1 0 0 1 1 1 1 7
3: 0 1 0 0 0 1 1 1 1 0 7
4: 0 0 0 1 1 0 1 1 1 1 7
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 7
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 8
2: 0 0 1 1 0 0 1 1 1 1 8
3: 0 1 0 0 0 1 1 1 1 0 8
4: 0 0 0 1 1 0 1 1 1 1 8
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 7
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 9
2: 0 0 1 1 0 0 1 1 1 1 9
3: 0 1 0 0 0 1 1 1 1 0 9
4: 0 0 0 1 1 0 1 1 1 1 9
5: 1 1 1 1 0 0 0 0 0 1 4
6: 1 1 0 1 1 0 1 0 1 1 9
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ans
1: 0 0 1 0 1 1 0 1 1 1 10
2: 0 0 1 1 0 0 1 1 1 1 10
3: 0 1 0 0 0 1 1 1 1 0 9
4: 0 0 0 1 1 0 1 1 1 1 10
5: 1 1 1 1 0 0 0 0 0 1 10
6: 1 1 0 1 1 0 1 0 1 1 10
>