[英]Conditional rowwise sum of subset of columns in specific row dplyr
我的問題有點棘手:我正在研究數據編輯,並且我即將找到正確的解決方案。 得到一個 dataframe 像這樣:
ID name var1 var2 var3 var_total
1 a 1 1 2 4
2 b 2 3 2 7
3 c 1 -1 -1 1
其中var_total
是從 var1 到 var3 的每個大於零的數字的總和。 比如說,在 ID == 2 上,我需要將 var2 更改為 -1,這樣做:
df %>% mutate(var2 = if_else(ID == 2, -1, var2))
這帶來了:
ID name var1 var2 var3 var_total
1 a 1 1 2 4
2 b 2 -1 2 7
3 c 1 -1 -1 1
問題是,我需要找到一種方法來自動重新計算該行的var_total
。 我知道如何為整個 dataframe 做到這一點,但這有點慢:
df %>%
rowwise() %>%
mutate(var_total = {
x <- c_across(starts_with('var'))
sum(x[x > 0])
})
有沒有辦法只對選定的ID
執行此操作? 在這種情況下,我最終的 dataframe 將是:
ID name var1 var2 var3 var_total
1 a 1 1 2 4
2 b 2 -1 2 4
3 c 1 -1 -1 1
謝謝!
如果您想有效地更新單行(或行的一小部分),我會使用直接分配,而不是dplyr
。
var_cols = grep(names(df), pattern = "var[0-9]+", value = T)
recalc_id = 2
df[df$ID %in% recalc_id, "var_total"] = apply(df[df$ID %in% recalc_id, var_cols], 1, \(x) sum(x[x > 0]))
正如 akrun 在評論中指出的那樣,如果它只是一行,則可以跳過apply
:
i = which(df$ID == recalc_id)
row = unlist(df[i, var_cols])
df$var_total[i] = sum(row[row > 0])
對於dplyr
解決方案,這與dplyr::case_when
相同:
df = df %>%
rowwise() %>%
mutate(var_total = case_when(
ID %in% 2 ~{
x <- c_across(starts_with('var[0-9]+'))
sum(x[x > 0])
},
TRUE ~ var_total
)
)
(請注意,在這兩種情況下,我們都需要將列名模式更改為在總和中不包括var_total
。)
rowwise
會破壞一些矢量化並減慢速度,因此,如果您非常擔心重新計算總和“太慢”的效率,我強烈推薦base
解決方案。 您甚至可能會找到一個非條件基本解決方案,該解決方案對於這種逐行操作來說足夠快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.