R 编程-从基于 100 个变量的值创建新变量
R Programming-Creating New variable from values based on 100 Variables
我设置了从 CFM_1 到 CFM_100 的 100 个变量。每个变量都可以取 1、2、3 或 4 中的任何值。我想创建一个名为 TEMP 的新变量,如果 CFM_1 到 CFM_100 变量中的任何一个值为 1,它将取值 1或 2. 请为此
提供适当的 R 代码帮助我
使用更有效的解决方案进行了编辑,部分来自@shayaa 的回答stolen/procured...
这里的第一行通过仅提取您感兴趣的列来创建一个临时数据框(我们将在完成后将其删除):
new <- subset( df, select = paste0( "CFM_", seq_len( 100 ) ) )
df$TEMP <- 1 * ( apply( new, 1, min ) <= 2 )
rm( new )
因此,您只需在每一行中搜索指定的任一值,然后将布尔结果转换为数字,然后将其放入原始数据框中。
我的例子有点傻,因为随机变量在这个矩阵中的单个位置生成 1 或 2 的几率是 1/2。这样做十次,矩阵的每一列一次,对于任何给定行,您的临时变量为 TRUE 的可能性小于 1%。无论如何,开始吧。
df <- data.frame(replicate(5, sample(1:4, 10, replace = TRUE)))
names(df) <- paste("CFM", 1:ncol(df), sep = "_")
你的数据框看起来像这样
df
CFM_1 CFM_2 CFM_3 CFM_4 CFM_5
1 2 2 1 4 4
2 2 2 1 3 4
3 2 1 1 3 3
4 1 2 3 3 2
5 3 4 2 4 4
6 3 4 4 2 2
7 3 1 3 2 2
8 1 2 4 1 2
9 3 2 1 3 2
10 1 3 1 4 3
现在假设您的数据框中还有其他您想要排除的变量。我们将使用 cbind 将这些列添加到您的数据框中,如下所示。
df <- cbind(replicate(3,sample(1:4, 10, replace = T)),
df,
replicate(3,sample(1:4, 10, replace = T)))
names(df)[1:3]<- paste0("Var",1:3)
names(df)[9:11] <- paste0("Var", 9:11)
现在你的 df 看起来像这样
df
Var1 Var2 Var3 CFM_1 CFM_2 CFM_3 CFM_4 CFM_5 Var9 Var10 Var11
1 4 1 4 4 1 3 1 3 1 3 1
2 4 2 3 2 4 3 2 1 2 3 3
3 4 2 4 4 2 1 1 2 2 3 2
4 4 4 2 4 4 1 3 2 2 1 2
5 4 2 1 4 4 4 1 1 2 2 2
6 1 4 2 3 1 4 4 2 1 3 2
7 3 2 4 4 2 3 4 3 1 1 1
8 1 3 3 3 3 2 3 3 2 2 2
9 3 3 2 1 4 3 4 1 4 2 1
10 2 1 1 2 1 2 4 1 2 1 1
您可以通过将 any 函数应用于数据行来为变量 temp 赋值,以检查每行中的任何数据是 1 还是 2。但首先您需要找出哪些列是您的数据。
您可以使用agrep
函数进行近似字符串匹配。如果您使用
,它会告诉您数据框的哪些名称中包含字符 "CFM"
cfm_cols <-agrep("CFM", names(df))
cfm_cols
[1] 4 5 6 7 8
temp <- apply(df[,cfm_cols], 1, function(x) any(x) %in% c(1,2))
temp
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
果然都是TRUE
.
如果您愿意,另一种解决方案是为此使用 dplyr
库
library(dplyr)
df%>% rowwise() %>% select(contains("CFM")) %>%
mutate(TEMP = any(.) %in% c(1,2))
我设置了从 CFM_1 到 CFM_100 的 100 个变量。每个变量都可以取 1、2、3 或 4 中的任何值。我想创建一个名为 TEMP 的新变量,如果 CFM_1 到 CFM_100 变量中的任何一个值为 1,它将取值 1或 2. 请为此
提供适当的 R 代码帮助我使用更有效的解决方案进行了编辑,部分来自@shayaa 的回答stolen/procured...
这里的第一行通过仅提取您感兴趣的列来创建一个临时数据框(我们将在完成后将其删除):
new <- subset( df, select = paste0( "CFM_", seq_len( 100 ) ) )
df$TEMP <- 1 * ( apply( new, 1, min ) <= 2 )
rm( new )
因此,您只需在每一行中搜索指定的任一值,然后将布尔结果转换为数字,然后将其放入原始数据框中。
我的例子有点傻,因为随机变量在这个矩阵中的单个位置生成 1 或 2 的几率是 1/2。这样做十次,矩阵的每一列一次,对于任何给定行,您的临时变量为 TRUE 的可能性小于 1%。无论如何,开始吧。
df <- data.frame(replicate(5, sample(1:4, 10, replace = TRUE)))
names(df) <- paste("CFM", 1:ncol(df), sep = "_")
你的数据框看起来像这样
df
CFM_1 CFM_2 CFM_3 CFM_4 CFM_5
1 2 2 1 4 4
2 2 2 1 3 4
3 2 1 1 3 3
4 1 2 3 3 2
5 3 4 2 4 4
6 3 4 4 2 2
7 3 1 3 2 2
8 1 2 4 1 2
9 3 2 1 3 2
10 1 3 1 4 3
现在假设您的数据框中还有其他您想要排除的变量。我们将使用 cbind 将这些列添加到您的数据框中,如下所示。
df <- cbind(replicate(3,sample(1:4, 10, replace = T)),
df,
replicate(3,sample(1:4, 10, replace = T)))
names(df)[1:3]<- paste0("Var",1:3)
names(df)[9:11] <- paste0("Var", 9:11)
现在你的 df 看起来像这样
df
Var1 Var2 Var3 CFM_1 CFM_2 CFM_3 CFM_4 CFM_5 Var9 Var10 Var11
1 4 1 4 4 1 3 1 3 1 3 1
2 4 2 3 2 4 3 2 1 2 3 3
3 4 2 4 4 2 1 1 2 2 3 2
4 4 4 2 4 4 1 3 2 2 1 2
5 4 2 1 4 4 4 1 1 2 2 2
6 1 4 2 3 1 4 4 2 1 3 2
7 3 2 4 4 2 3 4 3 1 1 1
8 1 3 3 3 3 2 3 3 2 2 2
9 3 3 2 1 4 3 4 1 4 2 1
10 2 1 1 2 1 2 4 1 2 1 1
您可以通过将 any 函数应用于数据行来为变量 temp 赋值,以检查每行中的任何数据是 1 还是 2。但首先您需要找出哪些列是您的数据。
您可以使用agrep
函数进行近似字符串匹配。如果您使用
"CFM"
cfm_cols <-agrep("CFM", names(df))
cfm_cols
[1] 4 5 6 7 8
temp <- apply(df[,cfm_cols], 1, function(x) any(x) %in% c(1,2))
temp
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
果然都是TRUE
.
如果您愿意,另一种解决方案是为此使用 dplyr
库
library(dplyr)
df%>% rowwise() %>% select(contains("CFM")) %>%
mutate(TEMP = any(.) %in% c(1,2))