如何按行更新 R data.table 的所有列?
How to update all columns of a R data.table by row?
我正在尝试通过从其他 data.table 中提取片段并组合它们来创建一个 data.table 对象。这是一个简单的例子:
a <- data.frame(x=1:30)
b <- data.frame(x=10:39)
c <- data.frame(x=20:49)
d <- data.frame(x=50:79)
e <- data.frame(x=60:89)
f <- data.frame(x=70:99)
DT <- data.table(matrix(ncol = 3, nrow = 30))
for (i in seq.int(from = 1, to = 30, by = 3)) {
set(DT,i,.SD,cbind(a[i,],b[i,],c[i,]))
set(DT,(i+1),.SD,cbind(d[i,],e[i,],f[i,]))
set(DT,(i+2),.SD,"")
}
但是这不起作用。我哪里做错了?谁能推荐一种更好的方法来实现这种效果?在R里这样循环我总觉得有点不自在
所需的输出应该是这样的:(显示前几行)
x x x
1: 1 10 20
2: 50 60 70
3:
4: 2 11 21
5: 51 61 71
6:
7: 3 12 22
8: 52 62 72
9:
10: 4 13 23
首先,您有冲突 类,因为您试图将数字和字符分配给相同的列。所以我将分配 NA
而不是 ""
.
也就是说,这是您使用 data.table
并进行一些修改后的解决方案:
DT <- data.table(matrix(0, ncol = 3, nrow = 30))
j = 1
cols = names(DT)
for (i in seq.int(from = 1, to = 30, by = 3)) {
DT[i , (cols) := .(a[j,], b[j,], c[j,])]
DT[i+1, (cols) := .(d[j,], e[j,], f[j,])]
DT[i+2, (cols) := NA]
j = j + 1
}
DT
V1 V2 V3
1: 1 10 20
2: 50 60 70
3: NA NA NA
4: 2 11 21
5: 51 61 71
6: NA NA NA
7: 3 12 22
8: 52 62 72
9: NA NA NA
10: 4 13 23
11: 53 63 73
12: NA NA NA
13: 5 14 24
14: 54 64 74
15: NA NA NA
16: 6 15 25
17: 55 65 75
18: NA NA NA
19: 7 16 26
20: 56 66 76
21: NA NA NA
22: 8 17 27
23: 57 67 77
24: NA NA NA
25: 9 18 28
26: 58 68 78
27: NA NA NA
28: 10 19 29
29: 59 69 79
30: NA NA NA
V1 V2 V3
另一个使用 apply
的解决方案(而不是使用 data.table
):
df <- apply(cbind(a,b,c,d,e,f), 1, function(x) rbind(data.frame(x=x[1], y=x[2], z=x[3]),
data.frame(x=x[4], y=x[5], z=x[6]),
data.frame(x=NA, y = NA, z = NA)))
df <- do.call("rbind", df)
可能有更有效的方法:
rows2<-seq.int(1,30,3)
rows3<-1:10
n2<-length(rows3)
h1<-list(a[rows3,],b[rows3,],c[rows3,])
h2<-list(d[rows3,],e[rows3,],f[rows3,])
h3<-list(rep("",n2),rep("",n2),rep("",n2))
DT <- data.table(matrix(0,ncol = 3, nrow = 30))
for (j in 1:3) {
set(DT,i=rows2,j=j,value=h1[[j]])
set(DT,i=rows2+1,j=j,value=h2[[j]])
set(DT,i=rows2+2,j=j,value=h3[[j]])
}
DT
V1 V2 V3
1: 1 10 20
2: 50 60 70
3: NA NA NA
4: 2 11 21
5: 51 61 71
6: NA NA NA
7: 3 12 22
8: 52 62 72
9: NA NA NA
10: 4 13 23
11: 53 63 73
12: NA NA NA
13: 5 14 24
14: 54 64 74
15: NA NA NA
16: 6 15 25
17: 55 65 75
18: NA NA NA
19: 7 16 26
20: 56 66 76
21: NA NA NA
22: 8 17 27
23: 57 67 77
24: NA NA NA
25: 9 18 28
26: 58 68 78
27: NA NA NA
28: 10 19 29
29: 59 69 79
30: NA NA NA
V1 V2 V3
基于@TimBiegeleisen 的回答,由于某种原因被删除:
library(data.table)
pt1 <- data.table(a,b,c)
pt2 <- data.table(d,e,f)
out <- rbind(pt1,pt2)
out[c(rbind(matrix(seq(1,nrow(out)),byrow=TRUE,nrow=2),NA))]
上面out
的行索引是这样的:1 31 NA 2 32 NA 3 33 NA
,所以抓取每组数据的第一行放在一起。 NA
索引生成一行的所有 NA
。
# x x x
# 1: 1 10 20
# 2: 50 60 70
# 3: NA NA NA
# 4: 2 11 21
# 5: 51 61 71
# 6: NA NA NA
# 7: 3 12 22
# 8: 52 62 72
# 9: NA NA NA
#10: 4 13 23
#...
我正在尝试通过从其他 data.table 中提取片段并组合它们来创建一个 data.table 对象。这是一个简单的例子:
a <- data.frame(x=1:30)
b <- data.frame(x=10:39)
c <- data.frame(x=20:49)
d <- data.frame(x=50:79)
e <- data.frame(x=60:89)
f <- data.frame(x=70:99)
DT <- data.table(matrix(ncol = 3, nrow = 30))
for (i in seq.int(from = 1, to = 30, by = 3)) {
set(DT,i,.SD,cbind(a[i,],b[i,],c[i,]))
set(DT,(i+1),.SD,cbind(d[i,],e[i,],f[i,]))
set(DT,(i+2),.SD,"")
}
但是这不起作用。我哪里做错了?谁能推荐一种更好的方法来实现这种效果?在R里这样循环我总觉得有点不自在
所需的输出应该是这样的:(显示前几行)
x x x
1: 1 10 20
2: 50 60 70
3:
4: 2 11 21
5: 51 61 71
6:
7: 3 12 22
8: 52 62 72
9:
10: 4 13 23
首先,您有冲突 类,因为您试图将数字和字符分配给相同的列。所以我将分配 NA
而不是 ""
.
也就是说,这是您使用 data.table
并进行一些修改后的解决方案:
DT <- data.table(matrix(0, ncol = 3, nrow = 30))
j = 1
cols = names(DT)
for (i in seq.int(from = 1, to = 30, by = 3)) {
DT[i , (cols) := .(a[j,], b[j,], c[j,])]
DT[i+1, (cols) := .(d[j,], e[j,], f[j,])]
DT[i+2, (cols) := NA]
j = j + 1
}
DT
V1 V2 V3
1: 1 10 20
2: 50 60 70
3: NA NA NA
4: 2 11 21
5: 51 61 71
6: NA NA NA
7: 3 12 22
8: 52 62 72
9: NA NA NA
10: 4 13 23
11: 53 63 73
12: NA NA NA
13: 5 14 24
14: 54 64 74
15: NA NA NA
16: 6 15 25
17: 55 65 75
18: NA NA NA
19: 7 16 26
20: 56 66 76
21: NA NA NA
22: 8 17 27
23: 57 67 77
24: NA NA NA
25: 9 18 28
26: 58 68 78
27: NA NA NA
28: 10 19 29
29: 59 69 79
30: NA NA NA
V1 V2 V3
另一个使用 apply
的解决方案(而不是使用 data.table
):
df <- apply(cbind(a,b,c,d,e,f), 1, function(x) rbind(data.frame(x=x[1], y=x[2], z=x[3]),
data.frame(x=x[4], y=x[5], z=x[6]),
data.frame(x=NA, y = NA, z = NA)))
df <- do.call("rbind", df)
可能有更有效的方法:
rows2<-seq.int(1,30,3)
rows3<-1:10
n2<-length(rows3)
h1<-list(a[rows3,],b[rows3,],c[rows3,])
h2<-list(d[rows3,],e[rows3,],f[rows3,])
h3<-list(rep("",n2),rep("",n2),rep("",n2))
DT <- data.table(matrix(0,ncol = 3, nrow = 30))
for (j in 1:3) {
set(DT,i=rows2,j=j,value=h1[[j]])
set(DT,i=rows2+1,j=j,value=h2[[j]])
set(DT,i=rows2+2,j=j,value=h3[[j]])
}
DT
V1 V2 V3
1: 1 10 20
2: 50 60 70
3: NA NA NA
4: 2 11 21
5: 51 61 71
6: NA NA NA
7: 3 12 22
8: 52 62 72
9: NA NA NA
10: 4 13 23
11: 53 63 73
12: NA NA NA
13: 5 14 24
14: 54 64 74
15: NA NA NA
16: 6 15 25
17: 55 65 75
18: NA NA NA
19: 7 16 26
20: 56 66 76
21: NA NA NA
22: 8 17 27
23: 57 67 77
24: NA NA NA
25: 9 18 28
26: 58 68 78
27: NA NA NA
28: 10 19 29
29: 59 69 79
30: NA NA NA
V1 V2 V3
基于@TimBiegeleisen 的回答,由于某种原因被删除:
library(data.table)
pt1 <- data.table(a,b,c)
pt2 <- data.table(d,e,f)
out <- rbind(pt1,pt2)
out[c(rbind(matrix(seq(1,nrow(out)),byrow=TRUE,nrow=2),NA))]
上面out
的行索引是这样的:1 31 NA 2 32 NA 3 33 NA
,所以抓取每组数据的第一行放在一起。 NA
索引生成一行的所有 NA
。
# x x x
# 1: 1 10 20
# 2: 50 60 70
# 3: NA NA NA
# 4: 2 11 21
# 5: 51 61 71
# 6: NA NA NA
# 7: 3 12 22
# 8: 52 62 72
# 9: NA NA NA
#10: 4 13 23
#...