【问题标题】:R - conditionally copy values from a column to a new column [duplicate]R - 有条件地将值从列复制到新列[重复]
【发布时间】:2017-03-16 06:45:43
【问题描述】:

我的数据如下所示:

Item | S1 | S2 | S3 | S4 | ID | New
A    | 1  | 2  | 5  | 8  | 1  |
A    | 4  | 4  | 5  | 4  | 1  |
A    | 6  | 7  | 1  | 3  | 1  |
A    | 4  | 1  | 7  | 6  | 1  |
B    | 3  | 1  | 5  | 3  | 2  |
B    | 1  | 4  | 5  | 2  | 2  |
B    | 8  | 7  | 3  | 6  | 2  |
B    | 4  | 1  | 5  | 2  | 2  |
C    | 4  | 2  | 6  | 4  | 4  |
C    | 6  | 6  | 7  | 1  | 4  |
C    | 2  | 3  | 3  | 7  | 4  |
C    | 5  | 8  | 9  | 2  | 4  |
D    | 2  | 1  | 2  | 3  | 3  |
D    | 2  | 6  | 7  | 6  | 3  |
D    | 2  | 3  | 0  | 4  | 3  |
D    | 2  | 1  | 2  | 1  | 3  |
E    | 6  | 1  | 3  | 5  | 4  |
E    | 3  | 2  | 4  | 4  | 4  |
E    | 6  | 6  | 7  | 7  | 4  |
E    | 3  | 8  | 1  | 4  | 4  |

根据每个“项目”的“ID”列下的值,我想用来自 S1、S2、S3 或 S4 的值填充“新”列。例如,由于 A 的 ID 为 1,我只希望 S1 下的值出现在新列中。

需要输出:

Item | S1 | S2 | S3 | S4 | ID | New
A    | 1  | 2  | 5  | 8  | 1  |  1
A    | 4  | 4  | 5  | 4  | 1  |  4
A    | 6  | 7  | 1  | 3  | 1  |  6
A    | 4  | 1  | 7  | 6  | 1  |  4
B    | 3  | 1  | 5  | 3  | 2  |  1
B    | 1  | 4  | 5  | 2  | 2  |  4
B    | 8  | 7  | 3  | 6  | 2  |  7
B    | 4  | 1  | 5  | 2  | 2  |  1
C    | 4  | 2  | 6  | 4  | 4  |  4
C    | 6  | 6  | 7  | 1  | 4  |  1
C    | 2  | 3  | 3  | 7  | 4  |  7
C    | 5  | 8  | 9  | 2  | 4  |  2
D    | 2  | 1  | 2  | 3  | 3  |  2
D    | 2  | 6  | 7  | 6  | 3  |  7
D    | 2  | 3  | 0  | 4  | 3  |  0
D    | 2  | 1  | 2  | 1  | 3  |  2
E    | 6  | 1  | 3  | 5  | 4  |  5
E    | 3  | 2  | 4  | 4  | 4  |  4
E    | 6  | 6  | 7  | 7  | 4  |  7
E    | 3  | 8  | 1  | 4  | 4  |  4

现在,我正在使用 for 循环来比较每个 Item 的 ID,并在循环中使用 paste0("S", counter_variable) 选择列。我的数据在“Item”下有大约 40,000 个不同的值和超过 1200 万行,而且需要很长时间。有没有更快的方法来做到这一点?

【问题讨论】:

  • 对于你的情况,它会是df[2:5][cbind(seq_along(df$ID), df$ID)]

标签: r


【解决方案1】:

也许您可以使用转换表。

data <- read.table("/home/wang/Downloads/test.txt", header = T, sep = "|")
tran_table <- paste0("S", 1:4)
names(tran_table) <- 1:4
data$ID <- tran_table[data$ID]

match_value <- function(ID_value){
  index <- which(data$ID == ID_value)
  data$New[index] <<- eval(parse(text = paste0("data$", ID_value)))[index]
  return(NULL)
}
apply(matrix(tran_table, ncol=1), 1, match_value)

结果是:

> data
   Item S1 S2 S3 S4 ID New
1     A  1  2  5  8 S1   1
2     A  4  4  5  4 S1   4
3     A  6  7  1  3 S1   6
4     A  4  1  7  6 S1   4
5     B  3  1  5  3 S2   1
6     B  1  4  5  2 S2   4
7     B  8  7  3  6 S2   7
8     B  4  1  5  2 S2   1
9     C  4  2  6  4 S4   4
10    C  6  6  7  1 S4   1
11    C  2  3  3  7 S4   7
12    C  5  8  9  2 S4   2
13    D  2  1  2  3 S3   2
14    D  2  6  7  6 S3   7
15    D  2  3  0  4 S3   0
16    D  2  1  2  1 S3   2
17    E  6  1  3  5 S4   5
18    E  3  2  4  4 S4   4
19    E  6  6  7  7 S4   7
20    E  3  8  1  4 S4   4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多