根据另一列中的值从多个列中选择一个项目

Choosing an item from several columns depending on a value in another column

我在 R 中的数据框有点问题。这是我的数据框的头部。

                         ID              X1 X2 X3     state
1 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     2
2 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     3
3 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     2
4 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     3
5 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     1
6 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     3

我想添加一个新列,其中包含列数 X1、X2、X3,但这取决于状态列。所以我想,如果我的状态是 1,我添加到 X1 列的列号,如果我的状态是 2,添加到 X2 的列号,如果我的状态是 3,我添加到 X3 的列号。所以,它看起来像这样:

                         ID              X1 X2 X3     state age
1 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     2     56
2 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     3     57
3 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     2     55
4 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     3     57
5 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     1     69
6 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     3     70

我该怎么做?我已经尝试过 ifelse 和子集,但它不起作用:(

ifelse 在这种情况下工作正常。尝试类似的东西:

dat <- read.table(text = "
ID              X1 X2 X3     state
1 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     2
2 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     3
3 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     2
4 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     3
5 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     1
6 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     3")

dat$age <- with(dat, ifelse(state == 1, X1, ifelse(state == 2, X2, X3)))

print(dat)
#                                      ID X1 X2 X3 state age
#1 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     2  56
#2 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     3  57
#3 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     2  55
#4 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     3  57
#5 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     1  69
#6 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     3  70

编辑如果你想使用索引,以下可能是一个选项

dat$age2 <- dat[cbind(1:nrow(dat), dat$state + 1)]
print(dat)
#                                      ID X1 X2 X3 state age age2
#1 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     2  56   56
#2 {026560B0-E0BB-4479-832D-2F5EFFAD9E9F} 56 56 57     3  57   57
#3 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     2  55   55
#4 {04E6B096-A3CC-4C82-9E01-69BB3D6A0CEF} 55 55 57     3  57   57
#5 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     1  69   69
#6 {089E7170-E221-46D9-AE2B-3CD7FB1FEE0B} 69 70 70     3  70   70

假设 'dat' 是数据帧的名称:

dat$age <- dat[ c("X1","X2", "X3" )][ cbind( seq_len(nrow(dat)), dat$state) ]

使用两列矩阵作为基本 R 索引策略之一的“[”的单个参数。如果查找工作是通过对不同行数或列数的 table 的索引完成的,并且可能会重复,那么您可以使用 matchfindInterval 来构建行或列向量。 Like @DavidArenburg I find ifelse to be clunky, especially when the number of options may grow.