[英]calculating percentages by category them in R
這是我的數據示例:
df <- read.table(header = TRUE, text = "book pen desk ipad 3 4 3 4 3 0 0 3 0 3 0 2 1 3 2 1 4 1 4 3 0 0 3 1 2 1 3 2 0 2 1 0 4 2 2 2 0 1 2 1 1 4 1 4 2 0 1 3 4 3 2 0 4 0 4 2" )
邏輯是我想要三個類別:低、中和高。
例如,考慮列 book,值 0 和 1= Low , 2= Medium , 3 和 4= High 。 接下來,我想計算每個類別的百分比。 如下所示,對於列簿中的 Low,百分比為 42.85。 我希望所有列都有這樣的輸出。 請考慮這只是一個示例。 謝謝你的幫助
Class Low Midium High book 42.85 xx xx pen xx xx xx desk xx xx xx ipad xx xx xx
ret <- t(sapply(df, function(a) {
lbls <- factor(c("Low", "Medium", "High"))
ct <- cut(a, c(0, 2, 4, Inf), right = FALSE, labels = lbls)
table(ct)
}))
t(apply(ret, 1, function(z) 100*z/sum(z)))
# Low Medium High
# book 42.85714 28.57143 28.57143
# pen 50.00000 35.71429 14.28571
# desk 35.71429 50.00000 14.28571
# ipad 35.71429 50.00000 14.28571
作為數據框:
out <- as.data.frame(t(apply(ret, 1, function(z) 100*z/sum(z))))
out$Class <- rownames(out)
# rownames(out) <- NULL # optional, if you don't want them
out <- out[,c(4,1:3)]
out
# Class Low Medium High
# book book 42.85714 28.57143 28.57143
# pen pen 50.00000 35.71429 14.28571
# desk desk 35.71429 50.00000 14.28571
# ipad ipad 35.71429 50.00000 14.28571
這是一個適合您的tidyverse
解決方案:
library(tidyverse)
df <- read.table(header = TRUE, text =
"book pen desk ipad
3 4 3 4
3 0 0 3
0 3 0 2
1 3 2 1
4 1 4 3
0 0 3 1
2 1 3 2
0 2 1 0
4 2 2 2
0 1 2 1
1 4 1 4
2 0 1 3
4 3 2 0
4 0 4 2"
)
df %>%
pivot_longer(1:4,
names_to = "Class",
values_to = "value") %>%
mutate(category = case_when(value %in% 0:1 ~ "l",
value == 2 ~ "m",
value %in% 3:4 ~ "h")) %>%
group_by(Class, category) %>%
count(category) %>%
pivot_wider(names_from = category, values_from = n) %>%
transmute(Class = Class,
High = h / sum(h, m, l)*100,
Medium = m / sum(h, m, l)*100,
Low = l / sum(h, m, l)*100)
結果表:
# A tibble: 4 x 4
# Groups: Class [4]
Class High Medium Low
<chr> <dbl> <dbl> <dbl>
1 book 42.9 14.3 42.9
2 desk 35.7 28.6 35.7
3 ipad 35.7 28.6 35.7
4 pen 35.7 14.3 50
附上一個可能的解決方案。 可能有更好的,但我會“自發地”想出它。
你好
df_test <- read.table(header = TRUE, text =
"book pen desk ipad
3 4 3 4
3 0 0 3
0 3 0 2
1 3 2 1
4 1 4 3
0 0 3 1
2 1 3 2
0 2 1 0
4 2 2 2
0 1 2 1
1 4 1 4
2 0 1 3
4 3 2 0
4 0 4 2"
)
low <- list()
medium <- list()
high <- list()
for(i in 1:ncol(df_test)) # i=1
{
low[[i]] <- ifelse((df_test[,i]==0 | df_test[,i]==1),df_test[,i],NA)
low[[i]] <- sum(colSums(!is.na(t(low[[i]])))) / length(low[[i]]) *100
medium[[i]] <- ifelse((df_test[,i]==2 | df_test[,i]==3),df_test[,i],NA)
medium[[i]] <- sum(colSums(!is.na(t(medium[[i]])))) / length(medium[[i]]) *100
high[[i]] <- ifelse((df_test[,i]==4 | df_test[,i]==5),df_test[,i],NA)
high[[i]] <- sum(colSums(!is.na(t(high[[i]])))) / length(high[[i]]) *100
}
names(low) <- colnames(df_test)
names(medium) <- colnames(df_test)
names(high) <- colnames(df_test)
df_test_final <- data.frame("Class"=colnames(df_test),"Low"=NA,"Medium"=NA,"High"=NA)
df_test_final[,2] <- do.call(rbind,low)
df_test_final[,3] <- do.call(rbind,medium)
df_test_final[,4] <- do.call(rbind,high)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.