【问题标题】:How can I use one column to determine where I get the value for another column?如何使用一列来确定从何处获取另一列的值?
【发布时间】:2015-02-21 01:21:45
【问题描述】:

我正在尝试使用一列来确定将哪一列用作另一列的值 它看起来像这样:

     X   Y  Z   Target
1    a   b  c    X
2    d   e  f    Y
3    g   h  i    Z

我想要一些看起来像这样的东西:

     X   Y  Z   Target  TargetValue
1    a   b  c    X           a
2    d   e  f    Y           e
3    g   h  i    Z           i

其中每个 TargetValue 是由 Target 指定的列确定的值。我一直在使用 dplyr 来让它工作。如果我知道如何使 paste 的输出成为 mutate 的输入,那就太好了,

mutate(TargetWordFixed = (paste("WordMove",TargetWord,".rt", sep="")))

但也许还有另一种方法可以做同样的事情。

温柔点,我是 stackoverflow 和 R 的新手...

【问题讨论】:

  • 一个简单的解决方案:df$target<-diag(as.matrix(df[,1:3]))?
  • @Metrics,这只是偶然的正确解决方案,但不是答案,因为它没有引用目标值中写入的内容。

标签: r dataframe dplyr


【解决方案1】:

矢量化方法是使用矩阵子集:

df %>% mutate(TargetValue = .[cbind(1:n(), match(Target, names(.)))])
#  X Y Z Target TargetValue
#1 a b c      X           a
#2 d e f      Y           e
#3 g h i      Z           i

或者只使用base R(同样的方法):

transform(df, TargetValue = df[cbind(1:nrow(df), match(Target, names(df)))])

解释:

  • match(Target, names(.)) 计算 Target 中条目的列索引(该列称为 X 等)
  • dplyr 版本中的. 指的是您使用%>% 将数据“管道”到mutate 语句中(即它指的是df
  • df[cbind(1:n(), match(Target, names(df))] 创建一个矩阵,将 df 子集设置为正确的值 - 矩阵的第一列只是从 1 到 df 的行数的行号(因此 1:nrow(df)),矩阵中的第二列是索引哪一列包含感兴趣的目标值(由match(Target, names(df)) 计算)。

为示例数据子集生成的矩阵是:

cbind(1:nrow(df), match(df$Target, names(df)))
     [,1] [,2]
[1,]    1    1
[2,]    2    2
[3,]    3    3

【讨论】:

  • 我需要花一些时间来了解所有这些都做了什么,但是你给我的 mutate 功能完全按照预期工作。谢谢!
  • @JoeJalbert,当然,一开始看起来很复杂。我试图在简短的解释中至少给你一些提示。
【解决方案2】:

您可以像这样尝试apply rowwise:

transform(df, TargetValue = apply(df, 1, function(x) x[x["Target"]]))
#   X Y Z Target TargetValue
# 1 a b c      X           a
# 2 d e f      Y           e
# 3 g h i      Z           i

【讨论】:

    【解决方案3】:
    library(tidyverse)
    
    df <-setNames(data.frame(cbind(matrix(letters[1:9],3,3,byrow=T), c("X", "Y", "Z"))), c("X", "Y", "Z", "Target"))
    
    df
    
    df %>% 
      gather(key="ID", value="TargetValue", X:Z) %>%
      filter(ID==Target) %>%
      select(Target, TargetValue) %>%
      left_join(df, by="Target")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-24
      • 2017-08-22
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多