[英]R rowSums for multiple groups of variables using mutate and for loops by prefix of variable names
我有多個變量按前綴(par___、fri___、gp___ 等)分組在一起,其中有 29 個。
每個變量的值為 0 或 1。我需要做的是對這些組求和(即,partner___1 + partner___2 等),如果 rowSums = 0,則使每個變量 NA。
例如。 我的數據如下所示:
標准桿 | 標准桿 2 | 星期五 1 | 星期五 2 |
---|---|---|---|
0 | 0 | 1 | 1 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 |
我希望它看起來像這樣:
標准桿 | 標准桿 2 | 星期五 1 | 星期五 2 |
---|---|---|---|
不適用 | 不適用 | 1 | 1 |
0 | 1 | 不適用 | 不適用 |
不適用 | 不適用 | 1 | 0 |
不適用 | 不適用 | 不適用 | 不適用 |
我可以像這樣單獨做:
df<- df%>%
mutate(rowsum = rowSums(.[grep("par___", names(.))])) %>%
mutate_at(grep("par___", names(.)), funs(ifelse(rowsum == 0, NA, .))) %>%
select(-rowsum)
我想我可以做這樣的事情:
vars <- c('par___', "fri___','gp___')
for (i in vars) {
df<- df%>%
# creates a "rowsum" column storing the sum of columns 1:2
mutate(rowsum = rowSums(.[grep(i, names(.))])) %>%
# applies, to columns 1:2, a function that puts NA when the sum of the rows is 0
mutate_at(grep(i, names(.)), funs(ifelse(rowsum == 0, NA, .))) %>%
select(-rowsum)
}
沒有錯誤消息,但它不起作用。
另外,我嘗試了 mutate(across()) 而不是 mutate_at() 並收到此錯誤:
錯誤: mutate()
輸入..1
有問題。 x 無法將列表轉換為 function i Input ..1
is cross across(grep(i, names(.)), list(ifelse(rowsum == 0, NA, .)))
。
而且,我試過 list 而不是 funs 並得到這個錯誤:
rowsum == 0 中的錯誤:比較 (1) 僅適用於原子和列表類型
任何幫助將不勝感激!
多謝了。
tidyverse 選項將是:
df %>%
stack() %>%
group_by(ind) %>%
group_by(grp = row_number(), grp2 = str_remove(ind, "_.*")) %>%
mutate(values = values + na_if(all(values==0), 1)) %>%
pivot_wider(grp, ind, values_from = values)
# A tibble: 4 x 5
# Groups: grp [4]
grp par___1 par___2 fri___1 fri___2
<int> <int> <int> <int> <int>
1 1 NA NA 1 1
2 2 0 1 NA NA
3 3 NA NA 1 0
4 4 NA NA NA NA
另一方面,如果您更喜歡基本 R,那么您可以這樣做:
d <- ave(unlist(df), row(df), sub("_.*", "", names(df))[col(df)], FUN = function(x) x * NA ^ all(x==0))
array(d, dim(df), dimnames(df))
par___1 par___2 fri___1 fri___2
1 NA NA 1 1
2 0 1 NA NA
3 NA NA 1 0
4 NA NA NA NA
請注意,最后一個是矩陣,您可以將其轉換為 dataframe。
使用split.default
基本 R 選項:
do.call(cbind, unname(lapply(split.default(df,
sub('(\\w+)_.*', '\\1', names(df))), function(x) {
x[rowSums(x) == 0, ] <- NA
x
})))
# fri___1 fri___2 par___ par___2
#1 1 1 NA NA
#2 NA NA 0 1
#3 1 0 NA NA
#4 NA NA NA NA
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.