我的数据如下:
ROW ID DV IDV
1 1 0 0.25
2 1 34 0.5
3 1 33 1
4 1 20 2
5 1 19 3
6 1 18 4
7 1 15 5
8 1 10 6
9 2 0 0.25
10 2 40 0.5
11 2 39 1
12 2 35 2
13 2 28 3
14 2 20 4
15 2 13 5
16 2 9 6
17 3 0 0.25
18 3 30 0.5
19 3 20 1
20 3 19 2
21 3 18 3
22 3 17 4
23 3 12 5
24 3 7 6
我希望它看起来像这样:
ROW ID DV IDV NEWDV
1 1 0 0.25 0
2 1 34 0.5 34
3 1 33 1 33
4 1 20 2 20
5 1 19 3 9.5
6 1 18 4 4.5
7 1 15 5 1.875
8 1 10 6 0.375
9 2 0 0.25 0
10 2 40 0.5 40
11 2 39 1 39
12 2 35 2 35
13 2 28 3 28
14 2 20 4 20
15 2 13 5 6.5
16 2 9 6 2.25
17 3 0 0.25 0
18 3 30 0.5 30
19 3 20 1 20
20 3 19 2 19
21 3 18 3 9
22 3 17 4 4.25
23 3 12 5 1.5
24 3 7 6 0.4375
我有很多像这样的数据集,我正在尝试为每个数据集完成相同的操作。那么,我想要做的是通过将DV值除以2,4,8,16,24,128等来创建一列NEWDV(即2提升到1,2,3,4,5,6,7和等等)。我想在IDV&gt;时才这样做2和DV <20。例如,取第21至24行,对于这四行的条件 DV&LT; 20和IDV>已经满足2并且NEWDV列读数为18/2 = 9,17 / 4 = 4.25,12 / 8 = 1.5,7 / 16 = 0.4375。必须为每个ID重置此计算。
我尝试使用以下代码但没有成功:
fc是具有数据的对象
x <- c(2,4,8,16)
for(i in 1:4){
for(j in 1:4){
for(g in 1:length(fc$DV<20 & fc$ID==i & fc$IDV>2)) {
fc$NEWDV[g] <-ifelse(fc$DV[fc$ID==i][g]<20 & fc$IDV[fc$ID==i][g]>2,fc$DV[fc$ID==i][g]/x[j],fc$DV[fc$ID==j][g])
}
}
}
我做错了什么?非常感谢帮助!!我想只为这个问题使用for循环。还欢迎任何其他解决方案。我只是熟悉for循环。谢谢。
答案 0 :(得分:3)
现在是时候使用cumsum
函数计算行数(包括当前行,其中条件(IDV&gt; 2和DV&lt; 20)为真)的行数;你可以将DV标准化为两个上升到这个累积和的幂。然后,您可以将此功能应用于按ID分解的数据框的每个部分。
# Split by ID
spl <- split(dat, dat$ID)
# Grab the normalized DV value for each grouping
new.dv <- lapply(spl, function(x) x$DV / 2^cumsum(x$IDV > 2 & x$DV < 20))
# Add the new values back to your data frame
dat$NEWDV <- unlist(new.dv)
dat
# ROW ID DV IDV NEWDV
# 1 1 1 0 0.25 0.0000
# 2 2 1 34 0.50 34.0000
# 3 3 1 33 1.00 33.0000
# 4 4 1 20 2.00 20.0000
# 5 5 1 19 3.00 9.5000
# 6 6 1 18 4.00 4.5000
# 7 7 1 15 5.00 1.8750
# 8 8 1 10 6.00 0.6250
# 9 9 2 0 0.25 0.0000
# 10 10 2 40 0.50 40.0000
# 11 11 2 39 1.00 39.0000
# 12 12 2 35 2.00 35.0000
# 13 13 2 28 3.00 28.0000
# 14 14 2 20 4.00 20.0000
# 15 15 2 13 5.00 6.5000
# 16 16 2 9 6.00 2.2500
# 17 17 3 0 0.25 0.0000
# 18 18 3 30 0.50 30.0000
# 19 19 3 20 1.00 20.0000
# 20 20 3 19 2.00 19.0000
# 21 21 3 18 3.00 9.0000
# 22 22 3 17 4.00 4.2500
# 23 23 3 12 5.00 1.5000
# 24 24 3 7 6.00 0.4375
这种分解数据框架,应用某种功能以及将结果组合在一起的方法称为split-apply-combine,是一种常见的数据争用方法。
答案 1 :(得分:1)
在这里,我们使用data.table
。转换&#34; data.frame&#34;到&#34; data.table&#34; (setDT(df)
)。创建新列(&#34; NEWDV&#34;将&#34; DV&#34;类转换为&#34;数字&#34 ;;逻辑&#34; indx&#34;列)。分配(:=
)&#34; NEWDV&#34;更改值(NEWDV/2^...
)当&#34; indx&#34;在按&#34; ID&#34;分组后,为TRUE((indx)
)。删除&#34; indx&#34;列通过将其分配给&#34; NULL&#34;
library(data.table)
setDT(df)[,c('NEWDV', 'indx'):= list(as.numeric(DV),
IDV>2 & DV <20)][(indx), NEWDV:=NEWDV/2^cumsum(indx), ID][,indx:=NULL][]
# ROW ID DV IDV NEWDV
# 1: 1 1 0 0.25 0.0000
# 2: 2 1 34 0.50 34.0000
# 3: 3 1 33 1.00 33.0000
# 4: 4 1 20 2.00 20.0000
# 5: 5 1 19 3.00 9.5000
# 6: 6 1 18 4.00 4.5000
# 7: 7 1 15 5.00 1.8750
# 8: 8 1 10 6.00 0.6250
# 9: 9 2 0 0.25 0.0000
# 10: 10 2 40 0.50 40.0000
# 11: 11 2 39 1.00 39.0000
# 12: 12 2 35 2.00 35.0000
# 13: 13 2 28 3.00 28.0000
# 14: 14 2 20 4.00 20.0000
# 15: 15 2 13 5.00 6.5000
# 16: 16 2 9 6.00 2.2500
# 17: 17 3 0 0.25 0.0000
# 18: 18 3 30 0.50 30.0000
# 19: 19 3 20 1.00 20.0000
# 20: 20 3 19 2.00 19.0000
# 21: 21 3 18 3.00 9.0000
# 22: 22 3 17 4.00 4.2500
# 23: 23 3 12 5.00 1.5000
# 24: 24 3 7 6.00 0.4375
df <- structure(list(ROW = 1:24, ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L), DV = c(0L, 34L, 33L, 20L, 19L, 18L, 15L, 10L, 0L, 40L, 39L,
35L, 28L, 20L, 13L, 9L, 0L, 30L, 20L, 19L, 18L, 17L, 12L, 7L),
IDV = c(0.25, 0.5, 1, 2, 3, 4, 5, 6, 0.25, 0.5, 1, 2, 3,
4, 5, 6, 0.25, 0.5, 1, 2, 3, 4, 5, 6)), .Names = c("ROW",
"ID", "DV", "IDV"), class = "data.frame", row.names = c(NA, -24L))