![](/img/trans.png)
[英]Problem with loop to add values from one dataframe and to another based on conditions
[英]Add New Columns to One Dataframe Based on Values and Functions in Another With Conditions in R
对你来说是一个棘手的问题。 我有两个数据框,一个是奇数比率列表(跳过第一个,因为它是我们的预测器)。 见下文:
变量的名称 | 赔率 |
---|---|
变量2 | 0.87 |
变量 3 | 1.42 |
变量4 | 2.10 |
变量5 | 0.56 |
变量6 | 1.01 |
第二个是主题列表,变量作为列,它是否以二进制标志(0/1)
的形式出现。 见下文:
主题名称 | Var 1(预测器) | 变量 2 | 变量 3 | 变量 4 | 变量 5 | 变量 6 |
---|---|---|---|---|---|---|
狗 | 1 | 0 | 1 | 0 | 0 | 1 |
猫 | 1 | 0 | 0 | 0 | 1 | 1 |
大象 | 0 | 0 | 0 | 0 | 0 | 0 |
熊 | 1 | 0 | 0 | 1 | 1 | 1 |
豺狼 | 0 | 0 | 0 | 0 | 0 | 1 |
我现在需要做的是通过它们的优势比添加x
个新变量(如果存在)。 例如。 Dog
有 2 个当前预测变量。 Var 3
和Var 6
所以我们想要Var3=1.42 * Var6=1.01
= 1.43 将其他的留空。 对于Jackal
,我们在Var 6=1.01
中有一个预测变量,其他变量留空。 将这些作为单个变量添加,并且它们的总乘法是首选。
变量的数量可能从五个、六个或七个变化,因此为 function 指定名称将不起作用。 它需要基于初始变量的数量(预测变量为-1)。
到目前为止,我已经尝试编写一个复杂的ifelse
语句,但它不适用于动态范围。 在匹配名称中添加前缀/后缀的内容? 还是通过 position? 我真的很难以最有效的方式做到这一点。 希望很清楚,如果需要/要求,很乐意提供更多详细信息。
让我们假设您的第一个数据框称为odds_df
,而您的第二个数据框称为presence_df
。 我已从您的问题中获取数据,并在此答案的底部制作了可重复的版本。
由于您的存在/不存在数据框中可能有不同数量的代表变量的列,您将需要某种方法来确定您尝试将哪些列与您的赔率数据匹配。 在您的示例数据中,这可能是根据变量名称,使用字符串匹配:
var_cols <- grep("^Var\\d+$", names(presence_df))
或者只是根据您知道哪些列是感兴趣的列:
var_cols <- 3:7
或者,如果前两列始终是名称和因变量,那么更通用的解决方案是:
var_cols <- 3:ncol(presence_df)
在这种情况下,这三种生成var_cols
的方法中的任何一种都会为您提供向量c(3, 4, 5, 6, 7)
。
您现在需要知道哪些赔率适用于哪些列,因此我们将存在/缺席数据框的列与赔率数据框中的正确行match
,如下所示:
var_rows <- match(names(presence_df)[var_cols], odds_df$`Variable Name`)
现在我们在 position 中获取我们需要应用于列的赔率向量:
odds_vec <- odds_df$Odds[var_rows]
为了获得应该适用于每个条目的正确赔率(给定存在或不存在),我们需要记住,由于赔率是乘法的,因此任何不存在的变量都应该被赋予值 1,而不是 0,这样它就不会影响赔率计算. 这意味着我们应该将存在/缺席数据的每一行乘以对数赔率,并对结果取幂以获得实际赔率。
我们可以使用apply
逐行执行此操作:
res <- t(apply(presence_df[var_cols], 1, function(x) exp(x * log(odds_vec))))
res
#> Var2 Var3 Var4 Var5 Var6
#> [1,] 1 1.42 1.0 1.00 1.01
#> [2,] 1 1.00 1.0 0.56 1.01
#> [3,] 1 1.00 1.0 1.00 1.00
#> [4,] 1 1.00 2.1 0.56 1.01
#> [5,] 1 1.00 1.0 1.00 1.01
现在我们可以将它写回到我们的存在/不存在数据框中,如下所示:
presence_df[var_cols] <- res
presence_df
#> Subject Name Var 1 (Predictor) Var2 Var3 Var4 Var5 Var6
#> 1 Dog 1 1 1.42 1.0 1.00 1.01
#> 2 Cat 1 1 1.00 1.0 0.56 1.01
#> 3 Elephant 0 1 1.00 1.0 1.00 1.00
#> 4 Bear 1 1 1.00 2.1 0.56 1.01
#> 5 Jackal 0 1 1.00 1.0 1.00 1.01
最后一步是计算存在或不存在变量所隐含的几率,这只是这些几率的逐行乘积:
presence_df$odds <- apply(presence_df[var_cols], 1, prod)
presence_df
#> Subject Name Var 1 (Predictor) Var2 Var3 Var4 Var5 Var6 odds
#> 1 Dog 1 1 1.42 1.0 1.00 1.01 1.43420
#> 2 Cat 1 1 1.00 1.0 0.56 1.01 0.56560
#> 3 Elephant 0 1 1.00 1.0 1.00 1.00 1.00000
#> 4 Bear 1 1 1.00 2.1 0.56 1.01 1.18776
#> 5 Jackal 0 1 1.00 1.0 1.00 1.01 1.01000
将几率转换为概率也可能会有所帮助,这样我们就可以在给定预测变量的情况下看到因变量存在的概率:
presence_df$prob <- presence_df$odds / (1 + presence_df$odds)
presence_df
#> Subject Name Var 1 (Predictor) Var2 Var3 Var4 Var5 Var6 odds prob
#> 1 Dog 1 1 1.42 1.0 1.00 1.01 1.43420 0.5891874
#> 2 Cat 1 1 1.00 1.0 0.56 1.01 0.56560 0.3612672
#> 3 Elephant 0 1 1.00 1.0 1.00 1.00 1.00000 0.5000000
#> 4 Bear 1 1 1.00 2.1 0.56 1.01 1.18776 0.5429115
#> 5 Jackal 0 1 1.00 1.0 1.00 1.01 1.01000 0.5024876
** 来自问题的数据以可重复的格式 **
odds_df <- structure(list(`Variable Name` = c("Var2", "Var3", "Var4", "Var5",
"Var6"), Odds = c(0.87, 1.42, 2.1, 0.56, 1.01)), row.names = c(NA,
-5L), class = "data.frame")
presence_df <- structure(list(`Subject Name` = c("Dog", "Cat", "Elephant",
"Bear", "Jackal"), `Var 1 (Predictor)` = c(1L, 1L, 0L, 1L, 0L), Var2 = c(0L,
0L, 0L, 0L, 0L), Var3 = c(1L, 0L, 0L, 0L, 0L), Var4 = c(0L, 0L,
0L, 1L, 0L), Var5 = c(0L, 1L, 0L, 1L, 0L), Var6 = c(1L, 1L, 0L,
1L, 1L)), class = "data.frame", row.names = c(NA, -5L))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.