我希望将data.frame列(下面的ser04)中的所有数值12345689替换为每个分组变量cat02的最小值sero04。我试图在网上找到任何一个例子但是失败了。这是一次尝试使用for循环,它不会像希望的那样运行。
year <- c(1999,2000,2001,2002,2003,2004)
ser01 <- c(42,43,55,86,117,123)
ser02 <- c(67,87,93,56,217,336)
ser03 <- c(12,63,85,86,117,123)
ser04 <- c(55, 123456789, 15,123456789,187,223)
ser05 <- c(77, 48, 55,86,117,123)
ser06 <- c(63, 41, 35,88,19,98)
ser07 <- c(47, 49, 74,116,147,183)
cat01 <- c("aa", "bb", "cc", "aa", "aa","cc")
cat02 <- c("ff", "ff", "gg", "gg", "hh","ff")
olddf <- data.frame(year,ser01,ser02,ser03,ser04,ser05,ser06,ser07,cat01,cat02)
newdf <- NULL
newdf <- as.data.frame(newTable)
n <- 0
for(i in 1:6){
for(j in 2:8){
n <- n+1
newdf[n, 1] <- as.numeric(olddf[i,j])
if(newdf[n, 1]==123456789) newdf[n, 1]<- min(olddf[i,1:4])
}
}
print(olddf)
print(newdf)
原始数据框看起来像
year ser01 ser02 ser03 ser04 ser05 ser06 ser07 cat01 cat02
1 1999 42 67 12 55 77 63 47 aa ff
2 2000 43 87 63 123456789 48 41 49 bb ff
3 2001 55 93 85 15 55 35 74 cc gg
4 2002 86 56 86 123456789 86 88 116 aa gg
5 2003 117 217 117 187 117 19 147 aa hh<
6 2004 123 336 123 223 123 98 183 cc ff
,结果数据框看起来像是
year ser01 ser02 ser03 ser04 ser05 ser06 ser07 cat01 cat02
1 1999 42 67 12 55 77 63 47 aa ff
2 2000 43 87 63 55 48 41 49 bb ff
3 2001 55 93 85 15 55 35 74 cc gg
4 2002 86 56 86 15 86 88 116 aa gg
5 2003 117 217 117 187 117 19 147 aa hh
6 2004 123 336 123 223 123 98 183 cc ff
但它没有...
[编辑:我注意到这段代码来自旧的尝试而且它没有引用组变量]
答案 0 :(得分:2)
@alexis_laz ave
解决方案很不错,但您也可以尝试data.table
或dplyr
来提高速度:
library(data.table)
newdf <- as.data.table(olddf)[, ser04 := ifelse(ser04 == 123456789, min(ser04), ser04), by = cat02]
# year ser01 ser02 ser03 ser04 ser05 ser06 ser07 cat01 cat02
# 1: 1999 42 67 12 55 77 63 47 aa ff
# 2: 2000 43 87 63 55 48 41 49 bb ff
# 3: 2001 55 93 85 15 55 35 74 cc gg
# 4: 2002 86 56 86 15 86 88 116 aa gg
# 5: 2003 117 217 117 187 117 19 147 aa hh
# 6: 2004 123 336 123 223 123 98 183 cc ff
或dplyr
library(dplyr)
newdf <-
olddf %>%
group_by(cat02) %>%
mutate(ser04 = ifelse(ser04 == 123456789, min(ser04), ser04))
答案 1 :(得分:1)
试试这个:
olddf$ser04[olddf$ser04==123456789] <-with(olddf, ave(ser04, cat02, FUN=min)[ser04==123456789])
olddf$ser04
#[1] 55 55 15 15 187 223