R - 有条件地将值从列复制到新列

时间:2017-03-16 06:45:43

标签: r

我的数据如下:

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  |

根据每个“Item”的“ID”列下的值,我想用S1,S2,S3或S4中的值填充“New”列。例如,由于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)选择列。我的数据在“项目”下有大约40,000个不同的值,超过1200万行,并且它将永远消失。有更快的方法吗?

1 个答案:

答案 0 :(得分:-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