![](/img/trans.png)
[英]is there a way in R such that the value of a column should be the one above if it meets a certain criteria in another column
[英]Is there a better way to find the percent of one column that meets a criteria for each value in another column for a data frame in R?
我有一個數據幀,其grade.equivalent
和scaled.score
,均為數值。 我想為每個年級或以上的所有學生找到等於或高於給定scaled.score
的學生grade.equivalent
。
例如,給定以下數據框:
df.ex <- data.frame(grade.equivalent=c(2.4,2.7,3.1,2.5,1.4,2.2,2.3,1.7,1.3,2.2),
scaled.score=c(187,277,308,268,236,305,298,246,241,138)
)
我想知道每個grade.equivalent
等於或高於該grade.equivalent
的學生中,得分高於301的學生中有grade.equivalent
。
為此,我執行了以下操作:
find.percent.basic <- function(cut.ge, data, cut.scaled.score){
df.sub <- subset(data, grade.equivalent >= cut.ge & !is.na(scaled.score))
denom <- nrow(df.sub)
df.sub <- subset(df.sub, scaled.score >= cut.scaled.score)
numer <- nrow(df.sub)
return(numer/denom)
}
grade.equivs <- unique(df.ex$grade.equivalent)
grade.equivs <- grade.equivs[order(grade.equivs)]
just.percs <- sapply(grade.equivs, find.percent.basic, data=df.ex, cut.scaled.score=301)
new.df <- data.frame(grade.equivalent=grade.equivs, perc=just.percs)
我計划將其包裝在一個函數中,並與plyr一起使用。
我的問題是,有更好的方法嗎? 似乎這可能是r的基函數或我不知道的通用包。
感謝您的任何想法。
編輯以澄清問題上面的代碼產生以下結果,這是我想要的結果:
grade.equivalent perc
1 1.3 0.2000000
2 1.4 0.2222222
3 1.7 0.2500000
4 2.2 0.2857143
5 2.3 0.2000000
6 2.4 0.2500000
7 2.5 0.3333333
8 2.7 0.5000000
9 3.1 1.0000000
根據@DWin的觀察結果,第二次編輯以進行澄清
布爾值的平均值是正確的百分比,因此應執行以下操作:
mean(data$scaled.score >= cut.ss, na.rm=TRUE)
如您的評論所述,是的,這正是您需要做的。 我選擇對scaled.score
訪問稍有不同,但沒有實際區別。
gs <- sort(unique(df.ex$grade.equivalent))
ps <- sapply(gs, function(cut.ge) {
mean(df.ex$scaled.score[df.ex$grade.equivalent>=cut.ge] >= 301, na.rm=TRUE)
})
data.frame(gs, ps)
# gs ps
# 1.3 0.2000000
# 1.4 0.2222222
# 1.7 0.2500000
# 2.2 0.2857143
# 2.3 0.2000000
# 2.4 0.2500000
# 2.5 0.3333333
# 2.7 0.5000000
# 3.1 1.0000000
我認為這不適用於plyr
的split-apply-combine方法,因為您不能將每個等值的數據拆分為離散的子集,相反,某些行會出現在多個子集。
另一種選擇是將分數(或整個數據框,如果需要)自己分割為所需的部分,然后應用所需的任何功能; 這將是與plyr
相同的方法,盡管更多是手工操作。
scores <- lapply(gs, function(x) df.ex$scaled.score[df.ex$grade.equivalent>=x])
sapply(scores, function(x) mean(x>301, na.rm=TRUE))
最后的選擇是將它們放到開始,然后計算一個累積平均值,並刪除重復的grade.equivalent
值,像這樣。
df2 <- df.ex[rev(order(df.ex$grade.equivalent)),]
df2$perc <- cumsum(df2$scaled.score>301)/1:nrow(df2)
df2 <- df2[nrow(df2):1,c("grade.equivalent", "perc")]
df2[!duplicated(df2$grade.equivalent),]
with(df.ex, tapply(scaled.score, INDEX=grade.equivalent,
FUN=function(s) 100*sum(s>301)/length(s) ) )
#1.3 1.4 1.7 2.2 2.3 2.4 2.5 2.7 3.1
# 0 0 0 50 0 0 0 0 100
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.