与标题一样,描述起来很复杂,所以我只会展示代码,我得到的以及我想要的内容。
set.seed(1)
df<-data.frame('X1'=rnorm(10),
'X2'=rnorm(10),
'X3'=c(c(rep('A',5)),c(rep('B',5))))
## create a bew column 'SPX2' which is the smallest positive number OF X2
## of each group(A and B)
require(data.table)
setDT(df)[X2>0,SPX2:=min(X2),by=X3]
df
然后我得到了结果:
X1 X2 X3 SPX2
1: -0.6264538 1.51178117 A 0.3898432
2: 0.1836433 0.38984324 A 0.3898432
3: -0.8356286 -0.62124058 A NA
4: 1.5952808 -2.21469989 A NA
5: 0.3295078 1.12493092 A 0.3898432
6: -0.8204684 -0.04493361 B NA
7: 0.4874291 -0.01619026 B NA
8: 0.7383247 0.94383621 B 0.5939013
9: 0.5757814 0.82122120 B 0.5939013
10: -0.3053884 0.59390132 B 0.5939013
我想要的是:
X1 X2 X3 SPX2
1: -0.6264538 1.51178117 A 0.3898432
2: 0.1836433 0.38984324 A 0.3898432
3: -0.8356286 -0.62124058 A 0.3898432
4: 1.5952808 -2.21469989 A 0.3898432
5: 0.3295078 1.12493092 A 0.3898432
6: -0.8204684 -0.04493361 B 0.5939013
7: 0.4874291 -0.01619026 B 0.5939013
8: 0.7383247 0.94383621 B 0.5939013
9: 0.5757814 0.82122120 B 0.5939013
10: -0.3053884 0.59390132 B 0.5939013
因为我想创建一个新列df$X4<-df$SPX2 - df$X2
,o要求SPX2
如上所述的任何其他操作。
我进行了搜索并发现了一些像here这样的帖子,但这不是我在这里尝试做的。
任何人都知道如何实现这一目标?
答案 0 :(得分:2)
tidyverse
替代方案:
df %>%
group_by(X3) %>%
mutate(SPX2 = min(X2[X2>0]))
给出:
X1 X2 X3 SPX2
<dbl> <dbl> <fctr> <dbl>
1 -0.6264538 1.51178117 A 0.3898432
2 0.1836433 0.38984324 A 0.3898432
3 -0.8356286 -0.62124058 A 0.3898432
4 1.5952808 -2.21469989 A 0.3898432
5 0.3295078 1.12493092 A 0.3898432
6 -0.8204684 -0.04493361 B 0.5939013
7 0.4874291 -0.01619026 B 0.5939013
8 0.7383247 0.94383621 B 0.5939013
9 0.5757814 0.82122120 B 0.5939013
10 -0.3053884 0.59390132 B 0.5939013
答案 1 :(得分:1)
使用data.table
包:
setDT(df)
df[,SPX2:=min(X2[X2 > 0]),by=X3]
这样做对于X3
的每个值,X2
的正值子集(即X2[X2 > 0]
),然后对所有正值取最小值。请注意,如果没有正值(即X2[X2 > 0]
为空),则结果值为Inf
。请记住这一点,尤其是如果您想使用SPX2
进行任何进一步的计算。
根据您的问题,为什么X2[X2 > 0]
有效,请按以下方式考虑:对于X3
的每个值,返回相应值X2
的向量。现在,您可以对此向量执行常规向量运算,其中一个向量通过X2 > 0
进行子集化。它的工作原理如下:
x2 = c(-1, 1, 2, 3, -2, 4)
x2[x2 > 0]
# [1] 1 2 3 4
希望这有帮助!