在其他列条件下递归操作 data.table 列
Manipulating data.table column recursively on other column condition
我需要计算数据框中的公式。为了简单起见,必须汇总几列中的每组值。但是,我不想跨行计算。我想根据其他地方的条件用另一组计算每组。
这就是我的意思:
我有一个 data.table.
data = data.table(A = c("a","c","b","b","a"),
B = c(1:5),
C = c(1:5)
)
setorder(data, by=A)
> data
A B C
1: a 1 1
2: a 5 5
3: b 3 3
4: b 4 4
5: c 2 2
在 D 列中,当 A 为“a”时,我需要汇总 B 和 C 中的值以及 B 和 C 中的值。由于我有多个“a”,因此需要进行多次聚合。应写入每个聚合的最小值。
这是一个例子。
对于第 1 行:(1+1)+(1+1)=4,(5+5)+(1+1)=12,所以 4 是最小值 - D1 =4。
对于第 3 行:(3+3)+(1+1)=8,(3+3)+(5+5)=16,D3 = 8。依此类推。
这就是我所期望的
> data_new
A B C D
1: a 1 1 4
2: a 5 5 12
3: b 3 3 8
4: b 4 4 10
5: c 2 2 6
我试过了,运行 遇到了问题。
for (i in data)data[i, D:=(min((data[i,B+C]) + (data[a=="a",(B+C)])))]
当我用 i 代替行号返回 min() returns 正确值的两个数字列表时,下面的最小选择表达式可以正常工作。下面的答案是 8.
min((data[3,B+C]) + (data[A=="a",(B+C)]))
我之前的尝试涉及 grid.expansion() 和 intersection()。然而,由于我的数据集的大小,我 运行 进入内存问题并且 Rstudio 退出了我。作为旁注,我需要 运行 计算,因为我无法事先用“a”预测最小结果 - 它是一组坐标,它们与答案的大小无关。
任何建议我的明显问题在哪里
您可以将 B + C
的值存储在变量 (val
) 中,其中 A = 'a'
。对于每一行,您可以取最小值 B + C + val
。
library(data.table)
val <- data[A =='a', B + C]
data[, D := min(B + C + val), seq_len(nrow(data))]
data
# A B C D
#1: a 1 1 4
#2: a 5 5 12
#3: b 3 3 8
#4: b 4 4 10
#5: c 2 2 6
您也可以使用 lapply
:
data[, D := lapply(B + C, function(x) min(x + val))]
一个选项也是在获取 'B'、'C' 的 min
之后复制 'a' 行,然后直接使用 +
'B'、'C' 列。优点是,我们不必分组或循环
library(data.table)
Reduce(`+`, (data[A == 'a', .(B = min(B), C = min(C))][rep(seq_len(.N), nrow(data))] + data[, .(B, C)]))
#[1] 4 12 8 10 6
或单行
data[, D := B + C + min(B[A== 'a']) + min(C[A== 'a'])]
data$D
#[1] 4 12 8 10 6
我需要计算数据框中的公式。为了简单起见,必须汇总几列中的每组值。但是,我不想跨行计算。我想根据其他地方的条件用另一组计算每组。 这就是我的意思: 我有一个 data.table.
data = data.table(A = c("a","c","b","b","a"),
B = c(1:5),
C = c(1:5)
)
setorder(data, by=A)
> data
A B C
1: a 1 1
2: a 5 5
3: b 3 3
4: b 4 4
5: c 2 2
在 D 列中,当 A 为“a”时,我需要汇总 B 和 C 中的值以及 B 和 C 中的值。由于我有多个“a”,因此需要进行多次聚合。应写入每个聚合的最小值。 这是一个例子。 对于第 1 行:(1+1)+(1+1)=4,(5+5)+(1+1)=12,所以 4 是最小值 - D1 =4。 对于第 3 行:(3+3)+(1+1)=8,(3+3)+(5+5)=16,D3 = 8。依此类推。 这就是我所期望的
> data_new
A B C D
1: a 1 1 4
2: a 5 5 12
3: b 3 3 8
4: b 4 4 10
5: c 2 2 6
我试过了,运行 遇到了问题。
for (i in data)data[i, D:=(min((data[i,B+C]) + (data[a=="a",(B+C)])))]
当我用 i 代替行号返回 min() returns 正确值的两个数字列表时,下面的最小选择表达式可以正常工作。下面的答案是 8.
min((data[3,B+C]) + (data[A=="a",(B+C)]))
我之前的尝试涉及 grid.expansion() 和 intersection()。然而,由于我的数据集的大小,我 运行 进入内存问题并且 Rstudio 退出了我。作为旁注,我需要 运行 计算,因为我无法事先用“a”预测最小结果 - 它是一组坐标,它们与答案的大小无关。
任何建议我的明显问题在哪里
您可以将 B + C
的值存储在变量 (val
) 中,其中 A = 'a'
。对于每一行,您可以取最小值 B + C + val
。
library(data.table)
val <- data[A =='a', B + C]
data[, D := min(B + C + val), seq_len(nrow(data))]
data
# A B C D
#1: a 1 1 4
#2: a 5 5 12
#3: b 3 3 8
#4: b 4 4 10
#5: c 2 2 6
您也可以使用 lapply
:
data[, D := lapply(B + C, function(x) min(x + val))]
一个选项也是在获取 'B'、'C' 的 min
之后复制 'a' 行,然后直接使用 +
'B'、'C' 列。优点是,我们不必分组或循环
library(data.table)
Reduce(`+`, (data[A == 'a', .(B = min(B), C = min(C))][rep(seq_len(.N), nrow(data))] + data[, .(B, C)]))
#[1] 4 12 8 10 6
或单行
data[, D := B + C + min(B[A== 'a']) + min(C[A== 'a'])]
data$D
#[1] 4 12 8 10 6