牧場名: 高橋牧場T
検定日: 2026年5月
検定頭数: 136 頭
calc_stats <- function(x) {
x <- as.numeric(x)
x <- x[!is.na(x) & is.finite(x)]
if (length(x) == 0) return(c(mean=NA, sd=NA, median=NA, min=NA, max=NA))
c(mean = round(mean(x), 2),
sd = round(sd(x), 2),
median = round(median(x), 2),
min = round(min(x), 2),
max = round(max(x), 2))
}
items <- c("乳量(kg)", "乳脂率(%)", "蛋白質率(%)", "乳糖率(%)",
"MUN(mg/dl)", "体細胞数(千/ml)", "体細胞スコア")
cols <- c("乳量_K", "乳脂率", "蛋白質率", "乳糖率",
"MUN", "体細胞数", "体細胞スコア")
stats_mat <- t(sapply(cols, function(col) calc_stats(data[[col]])))
stats_df <- data.frame(項目 = items,
平均値 = stats_mat[, "mean"],
標準偏差 = stats_mat[, "sd"],
中央値 = stats_mat[, "median"],
最小値 = stats_mat[, "min"],
最大値 = stats_mat[, "max"],
stringsAsFactors = FALSE)
kable(stats_df, caption = "検定結果統計", row.names = FALSE)
| 項目 | 平均値 | 標準偏差 | 中央値 | 最小値 | 最大値 |
|---|---|---|---|---|---|
| 乳量(kg) | 41.50 | 9.84 | 40.60 | 16.40 | 63.70 |
| 乳脂率(%) | 4.21 | 0.81 | 4.20 | 2.00 | 6.26 |
| 蛋白質率(%) | 3.54 | 0.36 | 3.55 | 1.61 | 4.43 |
| 乳糖率(%) | 4.53 | 0.24 | 4.56 | 2.37 | 4.93 |
| MUN(mg/dl) | 10.61 | 1.62 | 10.50 | 3.20 | 15.20 |
| 体細胞数(千/ml) | 222.04 | 868.66 | 36.50 | 3.00 | 8692.00 |
| 体細胞スコア | 1.99 | 1.93 | 2.00 | 0.00 | 9.00 |
dry_days <- as.numeric(data$乾乳日数)
dry_days <- dry_days[!is.na(dry_days) & dry_days != 0]
calving_int <- as.numeric(data$分娩間隔初産月齢[as.numeric(data$産次) != 1])
first_calv <- as.numeric(data$分娩間隔初産月齢[as.numeric(data$産次) == 1])
repro_items <- c("産次", "搾乳日数", "乾乳日数", "分娩間隔", "初産分娩月齢", "空胎日数", "授精回数")
repro_vals <- list(as.numeric(data$産次), as.numeric(data$搾乳日数),
dry_days, calving_int, first_calv,
as.numeric(data$空胎日数), as.numeric(data$授精回数))
repro_mat <- t(sapply(repro_vals, calc_stats))
repro_df <- data.frame(項目 = repro_items,
平均値 = repro_mat[, "mean"],
標準偏差 = repro_mat[, "sd"],
中央値 = repro_mat[, "median"],
最小値 = repro_mat[, "min"],
最大値 = repro_mat[, "max"],
stringsAsFactors = FALSE)
kable(repro_df, caption = "繁殖成績統計", row.names = FALSE)
| 項目 | 平均値 | 標準偏差 | 中央値 | 最小値 | 最大値 |
|---|---|---|---|---|---|
| 産次 | 3.43 | 1.61 | 3 | 1 | 7 |
| 搾乳日数 | 181.68 | 126.23 | 157 | 13 | 727 |
| 乾乳日数 | 67.17 | 31.65 | 62 | 26 | 192 |
| 分娩間隔 | 406.19 | 65.63 | 396 | 318 | 675 |
| 初産分娩月齢 | 23.71 | 2.70 | 23 | 21 | 31 |
| 空胎日数 | 104.38 | 83.83 | 72 | 12 | 636 |
| 授精回数 | 1.73 | 1.08 | 1 | 1 | 6 |
data_parity <- data %>%
mutate(
産次_num = as.numeric(産次),
産次グループ = case_when(
産次_num == 1 ~ "1産",
産次_num == 2 ~ "2産",
産次_num >= 3 ~ "3産以上",
TRUE ~ NA_character_
)
) %>%
filter(!is.na(産次グループ))
parity_summary <- data_parity %>%
group_by(産次グループ) %>%
summarise(
頭数 = n(),
平均乳量_kg = round(mean(as.numeric(乳量_K), na.rm = TRUE), 2),
平均体細胞数 = round(mean(as.numeric(体細胞数), na.rm = TRUE), 2),
平均体細胞スコア = round(mean(as.numeric(体細胞スコア), na.rm = TRUE), 2),
.groups = "drop"
) %>%
mutate(割合 = round(頭数 / sum(頭数) * 100, 1))
total_row <- data.frame(
産次グループ = "合計",
頭数 = sum(parity_summary$頭数),
平均乳量_kg = round(mean(as.numeric(data_parity$乳量_K), na.rm = TRUE), 2),
平均体細胞数 = round(mean(as.numeric(data_parity$体細胞数), na.rm = TRUE), 2),
平均体細胞スコア = round(mean(as.numeric(data_parity$体細胞スコア), na.rm = TRUE), 2),
割合 = 100.0,
stringsAsFactors = FALSE
)
parity_summary <- bind_rows(parity_summary, total_row)
parity_summary$産次グループ <- factor(parity_summary$産次グループ,
levels = c("1産", "2産", "3産以上", "合計"))
parity_summary <- parity_summary[order(parity_summary$産次グループ), ]
kable(parity_summary, caption = "産次別乳量と体細胞", row.names = FALSE)
| 産次グループ | 頭数 | 平均乳量_kg | 平均体細胞数 | 平均体細胞スコア | 割合 |
|---|---|---|---|---|---|
| 1産 | 21 | 33.00 | 30.67 | 0.95 | 15.4 |
| 2産 | 19 | 39.84 | 74.37 | 1.79 | 14.0 |
| 3産以上 | 96 | 43.69 | 293.14 | 2.25 | 70.6 |
| 合計 | 136 | 41.50 | 222.04 | 1.99 | 100.0 |
parity_305 <- data_parity %>%
group_by(産次グループ) %>%
summarise(
頭数 = n(),
平均305日乳量_kg = round(mean(as.numeric(乳量_305日), na.rm = TRUE), 2),
平均補正乳量_kg = round(mean(as.numeric(補正乳量), na.rm = TRUE), 2),
.groups = "drop"
) %>%
mutate(割合 = round(頭数 / sum(頭数) * 100, 1))
total_305 <- data.frame(
産次グループ = "合計",
頭数 = sum(parity_305$頭数),
平均305日乳量_kg = round(mean(as.numeric(data_parity$乳量_305日), na.rm = TRUE), 2),
平均補正乳量_kg = round(mean(as.numeric(data_parity$補正乳量), na.rm = TRUE), 2),
割合 = 100.0,
stringsAsFactors = FALSE
)
parity_305 <- bind_rows(parity_305, total_305)
parity_305$産次グループ <- factor(parity_305$産次グループ,
levels = c("1産", "2産", "3産以上", "合計"))
parity_305 <- parity_305[order(parity_305$産次グループ), ]
kable(parity_305, caption = "産次別305日乳量と補正乳量", row.names = FALSE)
| 産次グループ | 頭数 | 平均305日乳量_kg | 平均補正乳量_kg | 割合 |
|---|---|---|---|---|
| 1産 | 21 | 9653.36 | 12528.55 | 15.4 |
| 2産 | 19 | 12714.30 | 13594.13 | 14.0 |
| 3産以上 | 96 | 13981.41 | 13171.92 | 70.6 |
| 合計 | 136 | 12470.51 | 13144.75 | 100.0 |
parity_repro <- data_parity %>%
group_by(産次グループ) %>%
summarise(
頭数 = n(),
平均搾乳日数 = round(mean(as.numeric(搾乳日数), na.rm = TRUE), 2),
平均空胎日数 = round(mean(as.numeric(空胎日数), na.rm = TRUE), 2),
平均授精回数 = round(mean(as.numeric(授精回数), na.rm = TRUE), 2),
.groups = "drop"
) %>%
mutate(割合 = round(頭数 / sum(頭数) * 100, 1))
total_repro <- data.frame(
産次グループ = "合計",
頭数 = sum(parity_repro$頭数),
平均搾乳日数 = round(mean(as.numeric(data_parity$搾乳日数), na.rm = TRUE), 2),
平均空胎日数 = round(mean(as.numeric(data_parity$空胎日数), na.rm = TRUE), 2),
平均授精回数 = round(mean(as.numeric(data_parity$授精回数), na.rm = TRUE), 2),
割合 = 100.0,
stringsAsFactors = FALSE
)
parity_repro <- bind_rows(parity_repro, total_repro)
parity_repro$産次グループ <- factor(parity_repro$産次グループ,
levels = c("1産", "2産", "3産以上", "合計"))
parity_repro <- parity_repro[order(parity_repro$産次グループ), ]
kable(parity_repro, caption = "産次別繁殖成績", row.names = FALSE)
| 産次グループ | 頭数 | 平均搾乳日数 | 平均空胎日数 | 平均授精回数 | 割合 |
|---|---|---|---|---|---|
| 1産 | 21 | 249.71 | 131.67 | 1.83 | 15.4 |
| 2産 | 19 | 179.95 | 89.89 | 1.57 | 14.0 |
| 3産以上 | 96 | 167.15 | 101.27 | 1.74 | 70.6 |
| 合計 | 136 | 181.68 | 104.38 | 1.73 | 100.0 |
top15_lifetime <- data %>%
filter(!is.na(通算乳量) & !is.na(拡大4桁)) %>%
mutate(通算乳量_num = as.numeric(通算乳量)) %>%
arrange(desc(通算乳量_num)) %>%
head(15) %>%
mutate(
順位 = 1:n(),
通算乳量_kg = format(round(通算乳量_num, 0), big.mark = ",")
) %>%
select(順位, 拡大4桁, 産次, 通算乳量_kg)
kable(top15_lifetime, caption = "生涯乳量TOP15", row.names = FALSE)
| 順位 | 拡大4桁 | 産次 | 通算乳量_kg |
|---|---|---|---|
| 1 | 1659 | 6 | 83,371 |
| 2 | 1551 | 7 | 82,510 |
| 3 | 1588 | 7 | 79,287 |
| 4 | 1955 | 5 | 76,459 |
| 5 | 1906 | 6 | 75,599 |
| 6 | 1892 | 6 | 75,280 |
| 7 | 1758 | 6 | 74,951 |
| 8 | 1645 | 7 | 71,276 |
| 9 | 1663 | 6 | 68,801 |
| 10 | 1786 | 5 | 68,233 |
| 11 | 1945 | 6 | 65,705 |
| 12 | 1767 | 6 | 64,774 |
| 13 | 1958 | 5 | 64,455 |
| 14 | 1973 | 4 | 61,984 |
| 15 | 1959 | 5 | 59,934 |
parity_fa <- data_parity %>%
group_by(産次グループ) %>%
summarise(
頭数 = n(),
平均デノボFA = round(mean(as.numeric(デノボFA), na.rm = TRUE), 2),
平均プレフォーム = round(mean(as.numeric(プレフォーム), na.rm = TRUE), 2),
.groups = "drop"
) %>%
mutate(割合 = round(頭数 / sum(頭数) * 100, 1))
total_fa <- data.frame(
産次グループ = "合計",
頭数 = sum(parity_fa$頭数),
平均デノボFA = round(mean(as.numeric(data_parity$デノボFA), na.rm = TRUE), 2),
平均プレフォーム = round(mean(as.numeric(data_parity$プレフォーム), na.rm = TRUE), 2),
割合 = 100.0,
stringsAsFactors = FALSE
)
parity_fa <- bind_rows(parity_fa, total_fa)
parity_fa$産次グループ <- factor(parity_fa$産次グループ,
levels = c("1産", "2産", "3産以上", "合計"))
parity_fa <- parity_fa[order(parity_fa$産次グループ), ]
kable(parity_fa, caption = "産次別脂肪酸組成", row.names = FALSE)
| 産次グループ | 頭数 | 平均デノボFA | 平均プレフォーム | 割合 |
|---|---|---|---|---|
| 1産 | 21 | 28.45 | 37.24 | 15.4 |
| 2産 | 19 | 28.83 | 35.47 | 14.0 |
| 3産以上 | 96 | 29.05 | 36.48 | 70.6 |
| 合計 | 136 | 28.92 | 36.46 | 100.0 |
milk_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(乳量_K)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
乳量_num = as.numeric(乳量_K),
グループ = ifelse(as.numeric(乳量_K) <= 20, "20kg以下", "21kg以上")
)
plot_ly(milk_data,
x = ~搾乳日数_num, y = ~乳量_num,
color = ~グループ,
colors = c("20kg以下" = "#F5576C", "21kg以上" = "#667EEA"),
text = ~paste("拡大4桁:", 拡大4桁, "<br>乳量(kg):", round(乳量_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8)) %>%
layout(title = "分娩後日数と乳量の関係",
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "乳量(kg)"),
hovermode = "closest")
low_milk <- data %>%
filter(!is.na(乳量_K) & as.numeric(乳量_K) <= 20) %>%
mutate(搾乳日数_num = as.numeric(搾乳日数)) %>%
arrange(搾乳日数_num) %>%
select(拡大4桁, 産次, 搾乳日数, 乳量_K, 体細胞数) %>%
head(50)
if (nrow(low_milk) > 0) {
cat(paste0("⚠️ **乳量20kg以下の牛: ", nrow(low_milk), "頭**\n\n"))
datatable(low_milk, options = list(pageLength = 10), rownames = FALSE)
} else {
cat("✅ 乳量20kg以下の牛はいません。\n")
}
## ⚠️ **乳量20kg以下の牛: 1頭**
top10_milk <- data %>%
filter(!is.na(乳量_K)) %>%
mutate(乳量_num = as.numeric(乳量_K)) %>%
arrange(desc(乳量_num)) %>%
head(10) %>%
mutate(順位 = 1:n()) %>%
select(順位, 拡大4桁, 産次, 搾乳日数, 体細胞数, 乳量_K)
kable(top10_milk, caption = "乳量の高い牛TOP10", row.names = FALSE)
| 順位 | 拡大4桁 | 産次 | 搾乳日数 | 体細胞数 | 乳量_K |
|---|---|---|---|---|---|
| 1 | 2086 | 4 | 38 | 13 | 63.7 |
| 2 | 1906 | 6 | 34 | 12 | 62.4 |
| 3 | 2075 | 4 | 63 | 10 | 62.1 |
| 4 | 2268 | 4 | 50 | 63 | 59.2 |
| 5 | 1945 | 6 | 41 | 16 | 59.1 |
| 6 | 1969 | 5 | 100 | 37 | 58.5 |
| 7 | 1955 | 5 | 213 | 20 | 57.4 |
| 8 | 1960 | 6 | 31 | 8 | 57.0 |
| 9 | 2314 | 3 | 83 | 179 | 56.0 |
| 10 | 2267 | 4 | 88 | 366 | 55.9 |
bhba_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(BHB)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
BHB_num = as.numeric(BHB)
) %>%
filter(搾乳日数_num <= 60) %>%
mutate(グループ = ifelse(BHB_num >= 0.13, "0.13以上", "問題なし"))
if (nrow(bhba_data) > 0) {
plot_ly(bhba_data,
x = ~搾乳日数_num, y = ~BHB_num,
color = ~グループ,
colors = c("0.13以上" = "#F5576C", "問題なし" = "#667EEA"),
text = ~paste("拡大4桁:", 拡大4桁, "<br>BHB(mmol/L):", round(BHB_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8)) %>%
layout(title = "分娩後60日以内のBHB値",
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "BHB(mmol/L)"),
hovermode = "closest")
} else {
cat("データがありません。\n")
}
high_bhba <- data %>%
filter(!is.na(搾乳日数) & !is.na(BHB)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
BHB_num = as.numeric(BHB)
) %>%
filter(搾乳日数_num <= 60 & BHB_num >= 0.13) %>%
arrange(desc(BHB_num)) %>%
select(拡大4桁, 産次, 搾乳日数, 乳量_K, BHB)
if (nrow(high_bhba) > 0) {
cat(paste0("⚠️ **プロピレングリコール投与推奨: ", nrow(high_bhba), "頭**\n\n"))
datatable(high_bhba, options = list(pageLength = 10), rownames = FALSE)
} else {
cat("✅ BHBA高値の牛はいません。\n")
}
## ⚠️ **プロピレングリコール投与推奨: 1頭**
denovo_milk_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(デノボMilk)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
デノボMilk_num = as.numeric(デノボMilk)
)
if (nrow(denovo_milk_data) > 0) {
all_mean <- mean(denovo_milk_data$デノボMilk_num, na.rm = TRUE)
all_median <- median(denovo_milk_data$デノボMilk_num, na.rm = TRUE)
d60 <- filter(denovo_milk_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$デノボMilk_num, na.rm = TRUE)
median_60 <- median(d60$デノボMilk_num, na.rm = TRUE)
plot_ly(denovo_milk_data,
x = ~搾乳日数_num, y = ~デノボMilk_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>デノボMilk(%):", round(デノボMilk_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数とデノボMilk(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "デノボMilk(%)"),
hovermode = "closest")
}
denovo_fa_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(デノボFA)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
デノボFA_num = as.numeric(デノボFA),
グループ = ifelse(as.numeric(デノボFA) < 22, "22%未満", "22%以上")
)
if (nrow(denovo_fa_data) > 0) {
all_mean <- mean(denovo_fa_data$デノボFA_num, na.rm = TRUE)
all_median <- median(denovo_fa_data$デノボFA_num, na.rm = TRUE)
d60 <- filter(denovo_fa_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$デノボFA_num, na.rm = TRUE)
median_60 <- median(d60$デノボFA_num, na.rm = TRUE)
plot_ly(denovo_fa_data,
x = ~搾乳日数_num, y = ~デノボFA_num,
color = ~グループ,
colors = c("22%未満" = "#F5576C", "22%以上" = "#667EEA"),
text = ~paste("拡大4桁:", 拡大4桁, "<br>デノボFA(%):", round(デノボFA_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8)) %>%
layout(title = paste0("分娩後日数とデノボFA(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "デノボFA(%)"),
hovermode = "closest")
}
low_denovo <- data %>%
filter(!is.na(搾乳日数) & !is.na(デノボFA)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
デノボFA_num = as.numeric(デノボFA)
) %>%
filter(搾乳日数_num <= 100 & デノボFA_num < 22) %>%
arrange(デノボFA_num) %>%
select(拡大4桁, 産次, 搾乳日数, 乳量_K, 体細胞数, デノボFA)
if (nrow(low_denovo) > 0) {
cat(paste0("⚠️ **分娩後100日以内でデノボFA 22%未満の牛: ", nrow(low_denovo), "頭**\n\n"))
datatable(low_denovo, options = list(pageLength = 10), rownames = FALSE)
} else {
cat("✅ デノボFA 22%未満の牛はいません。\n")
}
## ⚠️ **分娩後100日以内でデノボFA 22%未満の牛: 3頭**
preform_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(プレフォーム)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
プレフォーム_num = as.numeric(プレフォーム)
)
if (nrow(preform_data) > 0) {
all_mean <- mean(preform_data$プレフォーム_num, na.rm = TRUE)
all_median <- median(preform_data$プレフォーム_num, na.rm = TRUE)
d60 <- filter(preform_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$プレフォーム_num, na.rm = TRUE)
median_60 <- median(d60$プレフォーム_num, na.rm = TRUE)
plot_ly(preform_data,
x = ~搾乳日数_num, y = ~プレフォーム_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>プレフォーム(%):", round(プレフォーム_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数とプレフォーム(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "プレフォーム(%)"),
hovermode = "closest")
}
fat_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(乳脂率)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
乳脂率_num = as.numeric(乳脂率)
)
if (nrow(fat_data) > 0) {
all_mean <- mean(fat_data$乳脂率_num, na.rm = TRUE)
all_median <- median(fat_data$乳脂率_num, na.rm = TRUE)
d60 <- filter(fat_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$乳脂率_num, na.rm = TRUE)
median_60 <- median(d60$乳脂率_num, na.rm = TRUE)
plot_ly(fat_data,
x = ~搾乳日数_num, y = ~乳脂率_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>乳脂率(%):", round(乳脂率_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数と乳脂率(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "乳脂率(%)"),
hovermode = "closest")
}
protein_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(蛋白質率)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
蛋白質率_num = as.numeric(蛋白質率)
)
if (nrow(protein_data) > 0) {
all_mean <- mean(protein_data$蛋白質率_num, na.rm = TRUE)
all_median <- median(protein_data$蛋白質率_num, na.rm = TRUE)
d60 <- filter(protein_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$蛋白質率_num, na.rm = TRUE)
median_60 <- median(d60$蛋白質率_num, na.rm = TRUE)
plot_ly(protein_data,
x = ~搾乳日数_num, y = ~蛋白質率_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>蛋白質率(%):", round(蛋白質率_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数と蛋白質率(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "蛋白質率(%)"),
hovermode = "closest")
}
lactose_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(乳糖率)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
乳糖率_num = as.numeric(乳糖率)
)
if (nrow(lactose_data) > 0) {
all_mean <- mean(lactose_data$乳糖率_num, na.rm = TRUE)
all_median <- median(lactose_data$乳糖率_num, na.rm = TRUE)
d60 <- filter(lactose_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$乳糖率_num, na.rm = TRUE)
median_60 <- median(d60$乳糖率_num, na.rm = TRUE)
plot_ly(lactose_data,
x = ~搾乳日数_num, y = ~乳糖率_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>乳糖率(%):", round(乳糖率_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数と乳糖率(%)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "乳糖率(%)"),
hovermode = "closest")
}
mun_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(MUN)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
MUN_num = as.numeric(MUN)
)
if (nrow(mun_data) > 0) {
all_mean <- mean(mun_data$MUN_num, na.rm = TRUE)
all_median <- median(mun_data$MUN_num, na.rm = TRUE)
d60 <- filter(mun_data, 搾乳日数_num <= 60)
mean_60 <- mean(d60$MUN_num, na.rm = TRUE)
median_60 <- median(d60$MUN_num, na.rm = TRUE)
plot_ly(mun_data,
x = ~搾乳日数_num, y = ~MUN_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>MUN(mg/dl):", round(MUN_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = paste0("分娩後日数とMUN(mg/dl)<br>全体: 平均 ", round(all_mean, 2),
" 中央値 ", round(all_median, 2),
" / 60日以内: 平均 ", round(mean_60, 2),
" 中央値 ", round(median_60, 2)),
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "MUN(mg/dl)"),
hovermode = "closest")
}
scc_data <- data %>%
filter(!is.na(搾乳日数) & !is.na(体細胞数)) %>%
mutate(
搾乳日数_num = as.numeric(搾乳日数),
体細胞数_num = as.numeric(体細胞数)
)
if (nrow(scc_data) > 0) {
plot_ly(scc_data,
x = ~搾乳日数_num, y = ~体細胞数_num,
text = ~paste("拡大4桁:", 拡大4桁, "<br>体細胞数(千/ml):", round(体細胞数_num, 2)),
hoverinfo = "text", type = "scatter", mode = "markers",
marker = list(size = 8, color = "#667EEA")) %>%
layout(title = "分娩後日数と体細胞数(千/ml)",
xaxis = list(title = "分娩後日数"),
yaxis = list(title = "体細胞数(千/ml)"),
hovermode = "closest")
}
top20_scc <- data %>%
filter(!is.na(体細胞数)) %>%
mutate(体細胞数_num = as.numeric(体細胞数)) %>%
arrange(desc(体細胞数_num)) %>%
head(20) %>%
mutate(順位 = 1:n()) %>%
select(順位, 拡大4桁, 産次, 搾乳日数, 体細胞数, 乳量_K)
kable(top20_scc, caption = "高体細胞数の牛TOP20", row.names = FALSE)
| 順位 | 拡大4桁 | 産次 | 搾乳日数 | 体細胞数 | 乳量_K |
|---|---|---|---|---|---|
| 1 | 2050 | 4 | 175 | 8692 | 49.1 |
| 2 | 1786 | 5 | 73 | 3887 | 38.9 |
| 3 | 1952 | 5 | 61 | 2914 | 43.4 |
| 4 | 2061 | 5 | 47 | 2173 | 38.9 |
| 5 | 2262 | 3 | 257 | 1243 | 38.1 |
| 6 | 2077 | 3 | 350 | 747 | 33.3 |
| 7 | 2085 | 4 | 128 | 577 | 51.7 |
| 8 | 1978 | 5 | 241 | 555 | 28.6 |
| 9 | 1947 | 4 | 474 | 513 | 25.5 |
| 10 | 2074 | 4 | 294 | 496 | 30.6 |
| 11 | 1659 | 6 | 462 | 488 | 32.5 |
| 12 | 2275 | 4 | 16 | 389 | 41.9 |
| 13 | 2267 | 4 | 88 | 366 | 55.9 |
| 14 | 2291 | 2 | 253 | 273 | 42.1 |
| 15 | 2083 | 4 | 256 | 269 | 37.2 |
| 16 | 2062 | 4 | 254 | 258 | 51.8 |
| 17 | 2308 | 2 | 334 | 228 | 38.2 |
| 18 | 2259 | 4 | 105 | 220 | 51.4 |
| 19 | 2057 | 4 | 366 | 219 | 34.2 |
| 20 | 2051 | 5 | 102 | 213 | 39.9 |
score_data <- data %>%
filter(!is.na(体細胞スコア)) %>%
mutate(体細胞スコア_round = round(as.numeric(体細胞スコア)))
if (nrow(score_data) > 0) {
score_counts <- score_data %>%
count(体細胞スコア_round) %>%
arrange(体細胞スコア_round)
plot_ly(score_counts,
x = ~体細胞スコア_round, y = ~n,
type = "bar",
marker = list(color = "#667EEA")) %>%
layout(title = "体細胞スコア分布",
xaxis = list(title = "体細胞スコア"),
yaxis = list(title = "頭数"))
}
score_parity_data <- data %>%
filter(!is.na(体細胞スコア) & !is.na(産次)) %>%
mutate(
体細胞スコア_round = round(as.numeric(体細胞スコア)),
産次_group = case_when(
as.numeric(産次) == 1 ~ "1",
as.numeric(産次) == 2 ~ "2",
as.numeric(産次) == 3 ~ "3",
as.numeric(産次) >= 4 ~ "4以上",
TRUE ~ NA_character_
)
) %>%
filter(!is.na(産次_group))
if (nrow(score_parity_data) > 0) {
score_parity_counts <- score_parity_data %>%
count(産次_group, 体細胞スコア_round) %>%
group_by(産次_group) %>%
mutate(percentage = n / sum(n) * 100) %>%
ungroup()
score_parity_counts$産次_group <- factor(score_parity_counts$産次_group,
levels = c("1", "2", "3", "4以上"))
plot_ly(score_parity_counts,
x = ~産次_group, y = ~percentage,
color = ~as.factor(体細胞スコア_round),
type = "bar",
text = ~paste0(round(percentage, 1), "%"),
textposition = "inside") %>%
layout(title = "産次ごとの体細胞スコア割合(100%積み上げ)",
xaxis = list(title = "産次"),
yaxis = list(title = "割合 (%)", range = c(0, 100)),
barmode = "stack",
legend = list(title = list(text = "スコア")))
}
作成日時: 2026-06-01 19:42:59.34943
Rバージョン: R version 4.3.2 (2023-10-31 ucrt)
使用パッケージ: readxl, dplyr, ggplot2, plotly, knitr, DT, tidyr
このレポートは以下の分析を含んでいます:
全てのグラフはインタラクティブで、マウスオーバーで詳細情報が表示されます。
使用方法:
excel_file_path <- "小森20260219.xlsx"
を実際のファイルのフルパスに変更必要なパッケージ: readxl, dplyr, ggplot2, plotly, knitr, DT, tidyr