使用其他列的某些行中的值创建新列

时间:2019-11-11 14:07:11

标签: r dataframe

我有一个看起来像这样的数据框: (示例已编辑)

df <- data.frame(Subject = c(rep("A", 9), rep("B", 8)),
Trial = c(1,1,2,3,4,4,5,6,6,1,2,2,3,4,5,5,6),
Feature_1 = c(rep(123, 2), 234, 345, rep(456, 2), 567, rep(678, 2), 831, rep(444, 2), 461, 921, rep(436, 2), 111),
Feature_2 = c(rep(321, 2), 543, 654, rep(765, 2), 876, rep(987, 2), 912, rep(302, 2), 900, 555, rep(382, 2), 197),
Feature_3 = c(rep(190, 2), 459, 392, rep(398, 2), 492, rep(587, 2), 761, rep(901, 2), 783, 312, rep(880, 2), 229),
Feature_correct = NA)

df
   Subject Trial Feature_1 Feature_2 Feature_3 Feature_correct
1        A     1       123       321       190              NA
2        A     1       123       321       190              NA
3        A     2       234       543       459              NA
4        A     3       345       654       392              NA
5        A     4       456       765       398              NA
6        A     4       456       765       398              NA
7        A     5       567       876       492              NA
8        A     6       678       987       587              NA
9        A     6       678       987       587              NA
10       B     1       831       912       761              NA
11       B     2       444       302       901              NA
12       B     2       444       302       901              NA
13       B     3       461       900       783              NA
14       B     4       921       555       312              NA
15       B     5       436       382       880              NA
16       B     5       436       382       880              NA
17       B     6       111       197       229              NA

我需要为Feature_correct列包含Feature_n中的值,具体取决于每个Trial的{​​{1}}。所以:

受试者A和试验1和2:Feature_correct分别包含Feature_1下受试者A和试验1和2的值。

受试者A和试验3和4:Feature_correct分别包含Feature_2下受试者A和试验3和4的值。

受试者A和试验5和6:Feature_correct分别包含Feature_3下受试者A和试验5和6的值。

以此类推,适用于主题B。

这是我的目标:

Subject

我知道如何手动执行此操作(在语法中指定“主题名称”和“试验编号”),但是我想创建一个循环(或其他可行的方法),这样我就不必键入名称每个主题(在我的真实数据集中,我有很多参与者和很多“功能”变量)。

我已经尝试过这个df$Feature_goal <- c(rep(123, 2), 234, 654, rep(765, 2), 492, rep(587, 2), 831, rep(444, 2), 900, 555, rep(880, 2), 229) head(df) Subject Trial Feature_1 Feature_2 Feature_3 Feature_correct Feature_goal 1 A 1 123 321 190 NA 123 2 A 1 123 321 190 NA 123 3 A 2 234 543 459 NA 234 4 A 3 345 654 392 NA 654 5 A 4 456 765 398 NA 765 6 A 4 456 765 398 NA 765 循环,但是遇到错误:

for

确实

df <- for(i in 1:nrow(df$Subject)) {
 if(df$Trial %in% c(1,2)){
   df[df$Subject == i $ df$Trial %in% c(1,2),]$Feature_correct = df[df$Subject == i & df$Trial %in% c(1,2),]$Feature_1
 }
  if(df$Trial %in% c(3,4)){
   df[df$Subject == i $ df$Trial %in% c(3,4),]$Feature_correct = df[df$Subject == i & df$Trial %in% c(3,4),]$Feature_2
  }
  if(df$Trial %in% c(5,6)){
   df[df$Subject == i $ df$Trial %in% c(5,6),]$Feature_correct = df[df$Subject == i & df$Trial %in% c(5,6),]$Feature_3
 }
}

> Error in 1:nrow(df$Subject) : argument of length 0

有人会(通过循环或任何其他方式)知道如何做到这一点吗?

2 个答案:

答案 0 :(得分:1)

一种矢量化的方法是通过使用原始数据帧中的列名和子集值将带有Trial号的“功能”粘贴到match来创建行/列索引。

df$Feature_Goal <- df[cbind(seq_len(nrow(df)), 
                      match(paste0("Feature_", df$Trial), names(df)))]
df

#   Subject Trial Feature_1 Feature_2 Feature_3 Feature_correct Feature_Goal
#1        A     1       123       321       190              NA          123
#2        A     1       123       321       190              NA          123
#3        A     2       234       543       459              NA          543
#4        A     2       234       543       459              NA          543
#5        A     3       345       654       392              NA          392
#6        A     3       345       654       392              NA          392
#7        B     1       456       765       398              NA          456
#8        B     1       456       765       398              NA          456
#9        B     2       567       876       492              NA          876
#10       B     2       567       876       492              NA          876
#11       B     3       678       987       587              NA          587
#12       B     3       678       987       587              NA          587

答案 1 :(得分:1)

这是使用循环的解决方案。

rvm