将数据框中的重复向量分配给 R 中的条件变量
Assign repeated vector in a dataframe to conditional variables in R
使用以下数据框:
indiv1 <- c('ID1','ID45','ID85','ID41','ID70','ID32','ID21','ID26')
indiv2 <- c('ID12',0,'ID3',0,'ID10','ID8',0,0)
df <- data.frame(indiv1,indiv2)
> df
indiv1 indiv2
1 ID1 ID12
2 ID45 0
3 ID85 ID3
4 ID41 0
5 ID70 ID10
6 ID32 ID8
7 ID21 0
8 ID26 0
我想添加一个列 V3
来分配一个向量 c(1,2,3)
,如果 indiv2==0
的长度大于我的长度,则重复 indiv2==0
向量。
我尝试使用 rep 函数:
df$V3 <- ifelse(df$indiv2==0,rep(1:3,length.out=dim(df[df$indiv2==0,])[1]),0)
> df
indiv1 indiv2 V3
1 ID1 ID12 0
2 ID45 0 2
3 ID85 ID3 0
4 ID41 0 1
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1
但它会计算 indiv2!=0
所在的行,以便在我希望的位置继续矢量:
> df
indiv1 indiv2 V3
1 ID1 ID12 0
2 ID45 0 1
3 ID85 ID3 0
4 ID41 0 2
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1
我们可以使用data.table
来做到这一点。将'data.frame'转换为'data.table'(setDT(df)
),然后在'i'(indiv2 == 0
)中指定逻辑条件,我们用[=复制1:3 17=] 作为行数 (.N
) 并将其分配 (:=
) 给 'V3',稍后我们将 NA 元素替换为 0.
library(data.table)
setDT(df)[indiv2==0, V3 := rep(1:3, length.out= .N)][is.na(V3), V3 := 0]
df
# indiv1 indiv2 V3
#1: ID1 ID12 0
#2: ID45 0 1
#3: ID85 ID3 0
#4: ID41 0 2
#5: ID70 ID10 0
#6: ID32 ID8 0
#7: ID21 0 3
#8: ID26 0 1
如果我们使用 base R
,创建一个逻辑向量
i1 <- df$indiv2 == 0
然后根据'i1'
创建'V3'列
df$V3[i1] <- rep(1:3, length.out = sum(i1))
并将 NA 替换为 0
df$V3[is.na(df$V3)] <- 0
df$V3
#[1] 0 1 0 2 0 0 3 1
使用 ifelse
要求 'yes' 和 'no' 参数的长度相同。这里,我们是基于rep
做回收,可能效果不好
你也可以用replace
一行完成。
df$v3 <- replace(numeric(nrow(df)), df$indiv2 == 0, 1:3)
它发出警告:
Warning message:
In replace(numeric(nrow(df)), df$indiv2 == 0, 1:3) :
number of items to replace is not a multiple of replacement length
但产生了预期的结果。
df
indiv1 indiv2 v3
1 ID1 ID12 0
2 ID45 0 1
3 ID85 ID3 0
4 ID41 0 2
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1
使用以下数据框:
indiv1 <- c('ID1','ID45','ID85','ID41','ID70','ID32','ID21','ID26')
indiv2 <- c('ID12',0,'ID3',0,'ID10','ID8',0,0)
df <- data.frame(indiv1,indiv2)
> df
indiv1 indiv2
1 ID1 ID12
2 ID45 0
3 ID85 ID3
4 ID41 0
5 ID70 ID10
6 ID32 ID8
7 ID21 0
8 ID26 0
我想添加一个列 V3
来分配一个向量 c(1,2,3)
,如果 indiv2==0
的长度大于我的长度,则重复 indiv2==0
向量。
我尝试使用 rep 函数:
df$V3 <- ifelse(df$indiv2==0,rep(1:3,length.out=dim(df[df$indiv2==0,])[1]),0)
> df
indiv1 indiv2 V3
1 ID1 ID12 0
2 ID45 0 2
3 ID85 ID3 0
4 ID41 0 1
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1
但它会计算 indiv2!=0
所在的行,以便在我希望的位置继续矢量:
> df
indiv1 indiv2 V3
1 ID1 ID12 0
2 ID45 0 1
3 ID85 ID3 0
4 ID41 0 2
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1
我们可以使用data.table
来做到这一点。将'data.frame'转换为'data.table'(setDT(df)
),然后在'i'(indiv2 == 0
)中指定逻辑条件,我们用[=复制1:3 17=] 作为行数 (.N
) 并将其分配 (:=
) 给 'V3',稍后我们将 NA 元素替换为 0.
library(data.table)
setDT(df)[indiv2==0, V3 := rep(1:3, length.out= .N)][is.na(V3), V3 := 0]
df
# indiv1 indiv2 V3
#1: ID1 ID12 0
#2: ID45 0 1
#3: ID85 ID3 0
#4: ID41 0 2
#5: ID70 ID10 0
#6: ID32 ID8 0
#7: ID21 0 3
#8: ID26 0 1
如果我们使用 base R
,创建一个逻辑向量
i1 <- df$indiv2 == 0
然后根据'i1'
创建'V3'列df$V3[i1] <- rep(1:3, length.out = sum(i1))
并将 NA 替换为 0
df$V3[is.na(df$V3)] <- 0
df$V3
#[1] 0 1 0 2 0 0 3 1
使用 ifelse
要求 'yes' 和 'no' 参数的长度相同。这里,我们是基于rep
做回收,可能效果不好
你也可以用replace
一行完成。
df$v3 <- replace(numeric(nrow(df)), df$indiv2 == 0, 1:3)
它发出警告:
Warning message: In replace(numeric(nrow(df)), df$indiv2 == 0, 1:3) :
number of items to replace is not a multiple of replacement length
但产生了预期的结果。
df
indiv1 indiv2 v3
1 ID1 ID12 0
2 ID45 0 1
3 ID85 ID3 0
4 ID41 0 2
5 ID70 ID10 0
6 ID32 ID8 0
7 ID21 0 3
8 ID26 0 1