我有一个矢量:
vec <- c(44,0,13,18,32,13,25,42,13,24)
我想按如下方式计算fT:
fT <- ifelse(vec >= 10 & vec <= 20, min(vec) - max(vec),
ifelse(vec > 20 & vec <= 50, max(vec) - min(vec),0))
我想为数据帧的每一行扩展此计算,即 我有一个数据帧,我想计算每一行的fT。
示例数据:
dat <- data.frame(replicate(10,sample(0:50,1000,rep=TRUE)))
这意味着我将拥有另一个数据帧,该数据帧将具有dat中每个值的fT值。
要计算每行的fT,我想到了dplyr
,
dat%>%
rowwise()%>%
mutate(fT = ifelse(dat[,1:10] >= 10 & dat[,1:10] <= 30, min(dat[,1:10]) - max(dat[,1:10]),
ifelse(dat[,1:10] > 30 & dat[,1:10] <= 50, max(dat[,1:10]) - min(dat[,1:10]),0)))
我被困在这个阶段。我不知道如何按列索引,以便dat
的每一行都有一个
fT
。
答案 0 :(得分:4)
如果您想要fT
的总和,可以使用apply
执行此操作:
dat$fT = apply(dat, 1, function(x) sum(ifelse(x >= 10 & x <= 20, min(x) - max(x),
ifelse(x > 20 & x <= 50, max(x) - min(x),0))))
<强>结果:强>
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 fT
1 14 13 8 10 15 12 22 47 29 40 -39
2 40 30 7 48 42 50 20 30 24 44 301
3 20 8 7 19 30 36 18 4 37 12 -33
4 45 43 26 31 41 33 26 43 11 28 272
5 47 43 25 9 14 12 3 1 38 46 138
6 2 24 31 33 7 4 36 41 42 0 252
注意:强>
1
中的 apply
指定行边距。这会循环输入行dat
,并为每行输出一个fT
的总和。
修改强>
如果您确实需要fT
的值(而不是总和),您仍然可以使用apply
,但请使用matrix
包装输出并指定ncol=10
和{ {1}}。这意味着您需要一个包含10列的输出矩阵(就像byrow=TRUE
一样)并使用dat
的输出逐行填充矩阵:
apply
<强>结果:强>
new_dat = matrix(apply(dat, 1,
function(x) ifelse(x >= 10 & x <= 20, min(x) - max(x),
ifelse(x > 20 & x <= 50, max(x) - min(x),0))),
ncol = 10, byrow = TRUE)
如果您更喜欢坚持> head(new_dat)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] -39 -39 0 -39 -39 -39 39 39 39 39
[2,] 43 43 0 43 43 43 -43 43 43 43
[3,] -33 0 0 -33 33 33 -33 0 33 -33
[4,] 34 34 34 34 34 34 34 34 -34 34
[5,] 46 46 46 0 -46 -46 0 0 46 46
[6,] 0 42 42 42 0 0 42 42 42 0
,则可以先dplyr
transpose
dat
{&#34;列&#34;},然后{{1}回复:
map
<强>结果:强>
transpose
注意:强>
在Base R中使用library(dplyr)
library(purrr)
dat %>%
transpose() %>%
map_dfr(~ ifelse(. >= 10 & . <= 20, min(.) - max(.),
ifelse(. > 20 & . <= 50, max(.) - min(.),0))) %>%
transpose()
代替> head(new_dat2)
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 -39 -39 0 -39 -39 -39 39 39 39 39
2 43 43 0 43 43 43 -43 43 43 43
3 -33 0 0 -33 33 33 -33 0 33 -33
4 34 34 34 34 34 34 34 34 -34 34
5 46 46 46 0 -46 -46 0 0 46 46
6 0 42 42 42 0 0 42 42 42 0
的好处是,您可以在转置而不是矩阵后获得data.frame。
数据:强>
transpose
答案 1 :(得分:0)
以下是pmax/pmin
的一个选项,效率很高
m1 <- (do.call(pmax, dat) - do.call(pmin, dat))[row(dat)]
out <- (-1*m1 *(dat >=10 & dat <=20)) + (m1*(dat > 20 & dat <=50))
all.equal(new_dat, out, check.attributes = FALSE)
#[1] TRUE
set.seed(24)
dat <- data.frame(replicate(500,sample(0:50,15000,rep=TRUE)))
system.time({
new_dat = matrix(apply(dat, 1,
function(x) ifelse(x >= 10 & x <= 20, min(x) - max(x),
ifelse(x > 20 & x <= 50, max(x) - min(x),0))),
ncol = ncol(dat), byrow = TRUE)
})
#user system elapsed
# 2.67 0.10 2.77
system.time({
m1 <- (do.call(pmax, dat) - do.call(pmin, dat))[row(dat)]
out <- (-1*m1 *(dat >=10 & dat <=20)) + (m1*(dat > 20 & dat <=50))
})
# user system elapsed
# 0.48 0.11 0.60
#all.equal(new_dat, out, check.attributes = FALSE)
#[1] TRUE