gpt4 book ai didi

rowMean 如果行通过测试

转载 作者:行者123 更新时间:2023-12-05 00:26:27 26 4
gpt4 key购买 nike

我正在处理一个数据集,其中源名称由变量前面的 2 个字母缩写指定。所以来自源 AA 的所有变量都以 AA_var1 开头,源 bb 有 bb_variable_name_2 。实际上有很多来源和很多变量名称,但我只留下 2 个作为最小示例。

我想为源数量(即该行上的数据不是 NA 的唯一前缀的数量)大于 1 的任何行创建一个均值变量。如果只有一个源,我想要那个总变量为 NA。

因此,例如,我的数据如下所示:

> head(df)
AA_var1 AA_var2 myid bb_meow bb_A_v1
1 NA NA 123456 10 12
2 NA 10 194200 12 NA
3 12 10 132200 NA NA
4 12 NA 132201 NA 12
5 NA NA 132202 NA NA
6 12 13 132203 14 NA

我想要以下内容:
> head(df)
AA_var1 AA_var2 myid bb_meow bb_A_v1 rowMeanIfDiverseData
1 NA NA 123456 10 12 NA #has only bb
2 NA 10 194200 12 NA 11 #has AA and bb
3 12 10 132200 NA NA NA #has only AA
4 12 NA 132201 NA 12 12 #has AA and bb
5 NA NA 132202 NA NA NA #has neither
6 12 13 132203 14 NA 13 #has AA and bb

通常,我只是将 rowMeans() 用于这种事情。但是仅选择变量名称遵循约定/在行级别/的行的附加子集让我在项目级别和我习惯的一般应用级别语句之间感到困惑。

我可以在数据帧级别获得前缀:
mynames <- names(df[!names(df) %in% c("myid")])
tmp <- str_extract(mynames, perl("[A-Za-z]{2}(?=_)"))
uniq <- unique(tmp[!is.na(tmp)])

所以,
> uniq
[1] "AA" "bb"

所以,我可以把它变成一个可以应用于 df 的函数,如下所示:
multiSource <- function(x){
nm = names(x[!names(x) %in% badnames]) # exclude c("myid")
tmp <- str_extract(nm, perl("[A-Za-z]{2}(?=_)")) # get prefixes
uniq <- unique(tmp[!is.na(tmp)]) # ensure unique and not NA
if (length(uniq) > 1){
return(T)
} else {
return(F)
}
}

但这显然令人困惑,并且仍然处于数据集级别,即:
> lapply(df,multiSource)
$AA_var1
[1] FALSE

$AA_var2
[1] FALSE

$bb_meow
[1] FALSE

$bb_A_v1
[1] FALSE

和...
> apply(df,MARGIN=1,FUN=multiSource)

为所有人提供 TRUE。

否则我想说...
df$rowMean <- rowMeans(df, na.rm=T)

# so, in this case
rowMeansIfTest <- function(X,test) {
# is this row muliSource True?
# if yes, return(rowMeans(X))
# else return(NA)
}

df$rowMeanIfDiverseData <- rowMeansIfTest(df, test=multiSource)

但是我不清楚如何在没有某种 for 循环的情况下做到这一点。

最佳答案

这里的策略是将数据框按列拆分为变量组,并为每一行标识是否存在非 NA 值。然后我们检查 rowsums 以确保至少有两个变量具有非 NA 值的行,如果是,则使用 cbind 添加这些值的平均值。

这将推广到任意数量的列,只要它们以 AA_varXXX 格式命名,并且只要不是该格式的唯一列是 myid 。如果情况并非如此,则很容易修复,但这些是对现在编写的代码的限制。

df.dat <- df[!names(df) == "myid"]
diverse.rows <- rowSums(
sapply(
split.default(df.dat, gsub("^([A-Z]{2})_var.*", "\\1", names(df.dat))),
function(x) apply(x, 1, function(y) any(!is.na(y)))
) ) > 1
cbind(df, div.mean=ifelse(diverse.rows, rowMeans(df.dat, na.rm=T), NA))

产生:
  AA_var1 AA_var2   myid BB_var3 BB_var4 div.mean
1 NA NA 123456 10 12 NA
2 NA 10 194200 12 NA 11
3 12 10 132200 NA NA NA
4 12 NA 132201 NA 12 12
5 NA NA 132202 NA NA NA
6 12 13 132203 14 NA 13

关于rowMean 如果行通过测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22180935/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com