好的,這個問題可能有點復雜,但我們開始吧。
我最近學習了如何使用 rowSums 來計算某個數字在一行中出現的次數。這是我正在使用的資料框:
Subjects LayCCD Day.1 Day.2 Day.3 Day.4 Day.5 Day.6 Day.7 Day.8
Subject 1 Day 2 1.0 0.0 0 1 1.0 1.5 200.0 1
Subject 2 Day 5 160.0 1.5 0 0 1.0 1.0 160.0 1
Subject 3 Day 4 0.0 0.0 0 1 1.0 1.0 1.0 0
Subject 4 Day 7 1.5 1.0 1 1 1.5 1.5 1.5 1
第一列有主題名稱/ID,第二列有 LayCCD(我要參考的變數),其余的是 Days。這是我到目前為止用來計算每行中出現 1、每行中出現 0 以及每行中出現 0 以外的任何數字的次數的代碼:
df$PresentAlone <- rowSums(df[,3:10] == "1")
df$Absent <- rowSums(df[,3:10] == "0")
df$Present <- rowSums(df[,3:10] != "0")
我基本上只是使用 rowSums 來計算從第 3 列到第 10 列(即第 1-8 天的列)出現 1、0 或非 0 的次數。該代碼給了我這個資料框:
Subjects LayCCD Day.1 Day.2 Day.3 Day.4 Day.5 Day.6 Day.7 Day.8 PresentAlone Absent Present
Subject 1 Day 2 1.0 0.0 0 1 1.0 1.5 200.0 1 4 2 6
Subject 2 Day 5 160.0 1.5 0 0 1.0 1.0 160.0 1 3 2 6
Subject 3 Day 4 0.0 0.0 0 1 1.0 1.0 1.0 0 4 4 4
Subject 4 Day 7 1.5 1.0 1 1 1.5 1.5 1.5 1 4 0 8
到目前為止這很好,但我需要做的一件事是計算行的特定部分,這些部分會因每個主題而異。例如,我可能只需要計算主題 1 的第 5-8 天,而計算主題 2 的第 3-7 天,依此類推。我正在處理一個大型資料集,所以這不是我想要手動執行的操作。
這就是“Lay CCD”列的用武之地。如您所見,Lay CCD 列包含每個主題的特定日期,范圍從 1 到 8。我想要做的是在 rowSums 公式中參考 LayCCD 中的該值,以便我可以根據該 LayCCD 值計算與上述相同的變數(1、0,而不是 0)。例如,如果我想從 LayCCD 數到主題 1 的 LayCCD 后 2 天,我希望 rowSums 公式僅計算從第 2 天到第 4 天的 1、0 和“非 0”的數量(第2 是 LayCCD,第 4 天是 LayCCD 后 2 天)。如果我對主題 2 執行相同的公式,我想將 LayCCD 計算到 Lay CCD 之后的兩天,則公式將從第 5 天計算到第 7 天(第 5 天是主題 2 的 LayCCD,第 7 天是兩天放置 CCD 后的幾天)。
基本上,如何使用 rowSums 公式來參考每一行的 LayCCD 值,以便我可以根據每個主題的 LayCCD 自動計算每行特定部分的特定值?
抱歉,如果這沒有意義,如果我需要澄清其他任何事情,請告訴我。我非常感謝您的幫助!!!
uj5u.com熱心網友回復:
不錯的腦筋急轉彎。即使我沒有使用過rowSums,我相信以下內容會有所幫助(盡管必須有更有效的方法來做到這一點)。
該函式ZeroAndOnes_fun()采用以下引數:
DF: 一個字串,表示data.frame要評估的。number_of_days: 一個整數,表示從 LayCCD(包括 LayCCD 本身指示的日期)開始計算的天數。例如,如果 LayCCD 等于主體 i 的“第 2 天”,則該函式將計算主體i在第 2、3 和 4 天的 0 和 1 的數量。before_LayCCD: 一個邏輯指示是否number_of_days應該從 LayCCD 向后計數或從 LayCCD 向前計數。例如,如果 LayCCD 等于主體i的“第 3 天”并before_LayCCD設定為,則該函式將計算主體iTRUE在第 3、2 和 1 天的 0 和 1 的數量。
ZeroAndOnes_fun <- function(DF, number_of_days, before_LayCCD = FALSE) {
days <- as.numeric(gsub('[^0-9]', '', DF$LayCCD))
id <- rep(seq_len(length(DF$Subjects)), each = number_of_days)
if (before_LayCCD){
days_to_count <- paste0(
'Day.', rep(days, each = number_of_days) - 0:(number_of_days-1L)
)
} else {
days_to_count <- paste0(
'Day.', rep(days, each = number_of_days) 0:(number_of_days-1L)
)
}
out <- data.frame(id, days_to_count)
out_list <- split(out, out$id)
mat <- matrix(numeric(length(out_list) * number_of_days),
ncol = number_of_days)
for (j in seq_along(out_list)) {
for (i in seq_len(number_of_days)) {
col_index <- lapply(out_list, '[', 'days_to_count')[[j]][[1L]][i]
mat[j, i] <- DF[j, col_index]
}
}
fun <- function(x) ifelse(length(x) == 0L, 0, x)
zeros <- ones <- numeric(length(out_list))
for (i in seq_len(length(out_list))) {
my_rle <- rle(mat[i, ])
zeros[i] <- fun(sum(my_rle$lengths[my_rle$values == 0L]))
ones[i] <- fun(sum(my_rle$lengths[my_rle$values == 1L]))
}
return(cbind(DF, zeros, ones))
}
輸出
> ZeroAndOnes_fun(DF = df, number_of_days = 2L, before_LayCCD = TRUE)
Subjects LayCCD Day.1 Day.2 Day.3 Day.4 Day.5 Day.6 Day.7 Day.8 Day.9 zeros ones
1 Subject1 Day 3 1.0 0.0 0 1 1.0 1.5 200.0 1 1 2 0
2 Subject2 Day 5 160.0 1.5 0 0 1.0 1.0 160.0 1 1 1 1
3 Subject3 Day 4 0.0 0.0 0 1 1.0 1.0 1.0 0 0 1 1
4 Subject4 Day 7 1.5 1.0 1 1 1.5 1.5 1.5 1 1 0 0
小基準。
# 1000 rows
df <- do.call(rbind, replicate(250, df, simplify = FALSE))
> system.time(ZeroAndOnes_fun(DF = df, number_of_days = 2L, before_LayCCD = TRUE))
user system elapsed
22.85 0.00 22.85
資料
df <- data.frame(
Subjects = paste0('Subject', 1:4),
LayCCD = paste0('Day ', c(3,5,4,7)),
Day.1 = c(1,160,0,1.5),
Day.2 = c(0,1.5,0,1),
Day.3 = c(0,0,0,1),
Day.4 = c(1,0,1,1),
Day.5 = c(1,1,1,1.5),
Day.6 = c(1.5,1,1,1.5),
Day.7 = c(200,160,1,1.5),
Day.8 = c(1,1,0,1),
Day.9 = c(1,1,0,1)
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/420251.html
標籤:
上一篇:獲取嵌套物件的所有不同鍵
