r - 在我的数据框中以其他列为条件填充一列,并使用第三列中的值

标签 r dataframe conditional multiple-columns

警告:这个问题似乎很简单,以至于我作为初学者可能无法在 SO 上更复杂的主题中找到正确的解决方案(查看 hereherehere 和更多地方)

我想根据另一列在我的数据框中填充一列,并将其他列用作输入。 举个例子就更清楚了:

  Version1 Version2 Version3 Version4 Presented_version Color
1     blue      red    green   yellow                 1    NA
2      red     blue   yellow    green                 4    NA
3   yellow    green      red     blue                 3    NA

我想用 Version1/Version2/Version3/Version 4 的值填充“Color”列。Presented_version 列告诉我这四个中的哪一个需要值(value)观。 例如,在第 1 行中,Prested_version 为 1,因此所需的值在“Version1”(“蓝色”)中。第 1 行的颜色应为蓝色。

有人可以告诉我一种方法来做到这一点,而无需使用大量“if”语句循环数据帧吗?

structure(list(Version1 = structure(1:3, .Label = c("blue", "red", 
"yellow"), class = "factor"), Version2 = structure(c(3L, 1L, 
2L), .Label = c("blue", "green", "red"), class = "factor"), Version3 = structure(c(1L, 
3L, 2L), .Label = c("green", "red", "yellow"), class = "factor"), 
    Version4 = structure(3:1, .Label = c("blue", "green", "yellow"
    ), class = "factor"), Presented_version = c(1L, 4L, 3L), 
    Color = c(NA, NA, NA)), class = "data.frame", row.names = c(NA, 
-3L))

======================== 已编辑!

我简化了示例来解释我的问题,但上面的示例在几个方面与我的实际数据集不同,因此解决方案做出了我的数据实际上不符合的假设。 这是 data.frame 的更准确表示。特别是,Prested_version 和 Version1...Version 4 列的内容之间没有固定的匹配(这取决于额外的列,我现在称之为 Painter),并且 Version1 到 Version4 不一定在列 1 到 4在我的数据集中。

  FillerColumn Painter Version1 Version2 Version3 Version4 Version_presented Color FillerColumn.1
1           77       A     blue      red    green   yellow                 1    NA             77
2           77       B      red     blue   yellow    green                 4    NA             77
3           77       C   yellow    green      red     blue                 3    NA             77
4           77       D      red     blue   yellow    green                 1    NA             77
structure(list(FillerColumn = c(77L, 77L, 77L, 77L), Painter = structure(1:4, .Label = c("A", 
"B", "C", "D"), class = "factor"), Version1 = structure(c(1L, 
2L, 3L, 2L), .Label = c("blue", "red", "yellow"), class = "factor"), 
    Version2 = structure(c(3L, 1L, 2L, 1L), .Label = c("blue", 
    "green", "red"), class = "factor"), Version3 = structure(c(1L, 
    3L, 2L, 3L), .Label = c("green", "red", "yellow"), class = "factor"), 
    Version4 = structure(c(3L, 2L, 1L, 2L), .Label = c("blue", 
    "green", "yellow"), class = "factor"), Version_presented = c(1L, 
    4L, 3L, 1L), Color = c(NA, NA, NA, NA), FillerColumn.1 = c(77L, 
    77L, 77L, 77L)), class = "data.frame", row.names = c(NA, 
-4L))

最佳答案

我们可以使用带有行/列索引的矢量化选项来提取值而不是任何循环

df1$color <- df1[1:4][cbind(1:nrow(df1), df1$Presented_version)]
df1$color
#[1] "blue"  "green" "red"  

基准

dfN <- df1[rep(seq_len(nrow(df1)), 1e6),]


system.time({
   dfN[1:4][cbind(1:nrow(dfN), dfN$Presented_version)]

 })
# user  system elapsed 
#   1.216   0.110   1.321


system.time({
 cols <- grep("^Version", names(dfN))
 unlist(mapply(function(x, y) dfN[x, cols][y], 
                    1:nrow(dfN),dfN$Presented_version))

 })
#  user  system elapsed 
# 319.907   1.644 322.418 

现在,让我们看看另一个选项 apply

system.time({
  apply(dfN, 1, function(x) x[cols][as.numeric(x["Presented_version"])])
 }) 
#  user  system elapsed 
# 14.240   0.365  14.550 

关于r - 在我的数据框中以其他列为条件填充一列,并使用第三列中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55379714/

相关文章:

r - 根据给定的顺序对数据框进行排序

javascript - 这是什么 JS 语法?表达式赋值? (x != null && (y = x))

php - 正则表达式 PHP IF 包含和限制

r - 如何将数据帧的内容写回范围?

Python:循环元组并将每个值插入到数据框中

python - 如何检测并重新运行程序运行时使用的函数?

iOS 应用程序设置包

r - 根据在一个衬管中删除 NA 的列的最大值获取名称

r - 结合训练+测试数据并在 R 中运行交叉验证

R:选择一组排放的第一行和最后一行(一次访问)并区分同一位置的不同访问