多组变量的 R rowSums 使用变量名称前缀的变异和 for 循环
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.
例如。我的数据如下所示:
par___
par___2
fri___1
fri___2
0
0
1
1
0
1
0
0
0
0
1
0
0
0
0
0
我希望它看起来像这样:
par___
par___2
fri___1
fri___2
NA
NA
1
1
0
1
NA
NA
NA
NA
1
0
NA
NA
NA
NA
我可以这样单独做:
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 无法将列表转换为函数
i 输入 ..1
是 across(grep(i, names(.)), list(ifelse(rowsum == 0, NA, .)))
.
而且,我尝试使用 list 而不是 funs 并得到这个错误:
行和错误 == 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
如果另一方面,您更喜欢 base 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
请注意,最后一个是矩阵,您可以将其转换为数据框。
Base R 选项使用 split.default
:
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
我有多个变量按前缀组合在一起(par___、fri___、gp___ 等),其中有 29 个这样的组。
每个变量的值为 0 或 1。我需要做的是对这些组求和(即 partner___1 + partner___2 等),如果 rowSums = 0,则使每个变量 NA.
例如。我的数据如下所示:
par___ | par___2 | fri___1 | fri___2 |
---|---|---|---|
0 | 0 | 1 | 1 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 |
我希望它看起来像这样:
par___ | par___2 | fri___1 | fri___2 |
---|---|---|---|
NA | NA | 1 | 1 |
0 | 1 | NA | NA |
NA | NA | 1 | 0 |
NA | NA | NA | NA |
我可以这样单独做:
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 无法将列表转换为函数
i 输入 ..1
是 across(grep(i, names(.)), list(ifelse(rowsum == 0, NA, .)))
.
而且,我尝试使用 list 而不是 funs 并得到这个错误:
行和错误 == 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
如果另一方面,您更喜欢 base 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
请注意,最后一个是矩阵,您可以将其转换为数据框。
Base R 选项使用 split.default
:
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