#r #loops #for-loop #nested #dplyr
#r #циклы #для цикла #вложенный #dplyr
Вопрос:
Я новичок в R, но здесь у меня есть фрейм данных из нескольких измерений пары условий, я хотел бы выполнить вложенный цикл по столбцам одного и того же условия, проверить, имеют ли они по крайней мере два истинных измерения (не ноль), если это так, вычислите среднее значение этих конкретных условий в новый набор данных.
> sample <- list(c(8,0,12,5,0,11), c(15,5,0,10,12,13), c(1,1,0,3,0,9),
c(11,9,8,0,4,7), c(12,5,5,0,9,0), c(1,7,2,0,8,0))
> sample <- as.data.frame(sample)
> colnames(sample) <- c("x.1","x.2","x.3","y.1","y.2","y.3")
> sample
x.1 x.2 x.3 y.1 y.2 y.3
1 8 15 1 11 12 1
2 0 5 1 9 5 7
3 12 0 0 8 5 2
4 5 10 3 0 0 0
5 0 12 0 4 9 8
6 11 13 9 7 0 0
Мой выходной набор данных в идеале должен выглядеть следующим образом:
> Newsample
x y
1 8 8
2 2 7
3 0 5
4 6 0
5 0 7
6 11 0
Ответ №1:
Мы определяем f_rowmean
функцию:
f_rowmean <- function(y) apply(y,1, function(x) ifelse(sum(x!=0)>=2, mean(x), 0))
И затем:
data.frame(x=f_rowmean(sample[,grep("x", names(sample))]),
y=f_rowmean(sample[,grep("y", names(sample))]))
# x y
# 1 8 8
# 2 2 7
# 3 0 5
# 4 6 0
# 5 0 7
# 6 11 0
Редактировать
Что касается новой постановки задачи OP (в комментариях), предположим, что ваш набор данных df1
включен, тогда вы могли бы сделать:
res.cols <- c("CAOV-3 Reg", "CAOV-3 Mod", "OVCAR-3Reg", "OVCAR-4Reg", "VOA1056Reg",
"VOA4698Reg", "VOA4698Mod", "TOV112DReg", "TOV112DMod", "TOV21G Mod",
"HCC38 Reg", "HCC38 Mod")
res <- setNames(data.frame(matrix(0,nrow(df1),length(res.cols))), res.cols)
res <- sapply(res.cols, function(x) res[,x] <- f_rowmean(df1[,grep(x, names(df1))]))
Комментарии:
1. Извините, я не прояснил это, но мой набор данных намного больше, чем этот фиктивный пример выше. На самом деле он состоит из 38 повторяющихся столбцов измерений, измеряющих 13 условий, поэтому я хотел бы создать один цикл, который проходит через весь фрейм данных, чтобы создать новый фрейм данных, а не только список x и y
2. Имена столбцов: «CAOV-3 Reg.1» «CAOV-3 Reg.2» «CAOV-3 Reg.3» «CAOV-3 Mod.1» «CAOV-3 Mod.2» «CAOV-3 Mod.3» «OVCAR-3Reg.1″»OVCAR-3Reg.2» «OVCAR-3Reg.3» «OVCAR-4Reg.1» «OVCAR-4Reg.2» «OVCAR-4Reg.3» «VOA1056Reg.1» «VOA1056Reg.2» «VOA1056Reg.3» «VOA4698Reg.1» «VOA4698Reg.2» «VOA1056Reg.3» «VOA4698Reg.1» «VOA4698Reg.2″»VOA4698Reg.3» «VOA4698Mod.1» «VOA4698Mod.2» «VOA4698Mod.3» «TOV112DMod.1» «TOV112DMod.2» «TOV112DMod.3» «TOV21G Reg.1» «TOV21G Reg.2» «TOV21G Reg.3» «TOV21G Reg.1» «TOV21G Reg.2» «TOV21G Reg.3» «TOV21G Mod.1» «TOV21G Mod.2» «TOV21G Mod.3» «HCC38 Reg.1» «HCC38 Reg.2» «HCC38 Mod.1» «HCC38 Mod.2» «HCC38 Mod.3»
3. И в идеале я хочу создать фрейм данных из:
4. > y2 [1] «CAOV-3 Reg» «CAOV-3 Mod» «OVCAR-3Reg» «OVCAR-4Reg» «VOA1056Reg» «VOA4698Reg» «VOA4698Mod» [8] «TOV112DReg» «TOV112DMod» «TOV21G Mod» «HCC38 Reg» «HCC38 Mod»
5. Работал отлично. Спасибо!
Ответ №2:
Мы перебираем индексы столбцов ‘x’ и ‘y’ в a list
, получаем rowSums
логическую матрицу of и используем ifelse
для получения rowMeans
data.frame(setNames(lapply(list(grep("^x", names(sample)),
grep("^y", names(sample))), function(i) {
x1 <- sample[i]
ifelse(rowSums(x1!=0)>1, rowMeans(x1), 0)}), c("x", "y")))
# x y
#1 8 8
#2 2 7
#3 0 5
#4 6 0
#5 0 7
#6 11 0
Комментарии:
1. Извините, я не прояснил это, но мой набор данных намного больше, чем этот фиктивный пример выше. На самом деле он состоит из 38 повторяющихся столбцов измерений, измеряющих 13 условий, поэтому я хотел бы создать один цикл, который проходит через весь фрейм данных, чтобы создать новый фрейм данных, а не только список x и y
2. @Mohere Это легко изменить