【问题标题】:How do I create a column based on values in another column which are the names of variables in my dataframe whose data I want to fill newcol with? R如何根据另一列中的值创建一列,这些值是我的数据框中的变量名称,我想用其数据填充 newcol? R
【发布时间】:2022-01-17 12:42:27
【问题描述】:

如果我的问题的表述令人困惑,我深表歉意,我无法找到类似的线索来澄清我的问题的英语。

我正在处理如下所示的数据样本:

label1 label2 label3 label#
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3

我正在尝试创建一个新列“currentvalue”,它读取某一行中标签# 的值,然后为该行填充该列的值,该行的值在标签# 中命名的任何列。换句话说,我希望我的输出看起来像这样:

label1 label2 label3 label# currentvalue
value1 value4 value7 label2 value4
value2 value5 value8 label1 value2
value3 value6 value9 label3 value9

我能想到的唯一解决方案涉及多个 for 循环,我认为这在计算上非常低效。我一直在寻找可以帮助我为此编写矢量化解决方案的线程的堆栈溢出,但我认为我无法很好地阐明这个问题,因为我的搜索都没有帮助。感谢您提供任何帮助(包括帮助更好地说明我的问题)。

【问题讨论】:

    标签: r dataframe dplyr tidyr data-wrangling


    【解决方案1】:

    有点乱,我认为可能有更好的方法,但你可以试试

    library(dplyr)
    library(tibble)
        
    df <- read.table(text = "label1 label2  label3  label#
    value1  value4  value7  label2
    value2  value5  value8  label1
    value3  value6  value9  label3", h = T)
    
    df %>%
      rowwise %>%
      rownames_to_column(., "row") %>%
      mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
    
      row   label1 label2 label3 label  currentvalue
      <chr> <chr>  <chr>  <chr>  <chr>  <chr>       
    1 1     value1 value4 value7 label2 value4      
    2 2     value2 value5 value8 label1 value2      
    3 3     value3 value6 value9 label3 value9 
    

    当我用read.table读取你的数据时,label#变成label

    列名label#

    names(df)[4] <- "label#"
    
    df %>%
      rowwise %>%
      rownames_to_column(., "row") %>%
      mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == 'label#')]])
    
      row   label1 label2 label3 `label#` currentvalue
      <chr> <chr>  <chr>  <chr>  <chr>    <chr>       
    1 1     value1 value4 value7 label2   label2      
    2 2     value2 value5 value8 label1   label1      
    3 3     value3 value6 value9 label3   label3  
    

    使用基础 R

    x <- match(df$label, names(df))
    y <- 1:nrow(df)
    z <- data.frame(y, x)
    df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
    

    时间检查

    microbenchmark::microbenchmark(
      a = {
        df %>%
          rowwise %>%
          rownames_to_column(., "row") %>%
          mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
      },
      b = {
        x <- match(df$label, names(df))
        y <- 1:nrow(df)
        z <- data.frame(y, x)
        df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
      }
    )
    
    Unit: microseconds
     expr    min      lq     mean  median     uq     max neval cld
        a 6157.8 6861.95 8773.098 7465.75 9367.1 26232.8   100   b
        b  360.6  399.75  692.073  488.40  666.9  4225.0   100  a 
    

    【讨论】:

    • 感谢您抽出宝贵时间回答!出于某种原因,当我将特定列名换成 label#/label 时,这段代码似乎永远运行。你知道这可能是什么原因吗?
    • @nlplearner 我无法理解 在标签#/标签的特定列名中交换部分。我在label# 是第 4 列名称时添加代码。
    • 我已经编辑了我的第一条评论,希望它更清楚。这里是:
    • 感谢您抽出宝贵时间回答!出于某种原因,当我将“标签#”更改为更大数据集列的名称时,此代码似乎永远运行。你知道这可能是什么原因吗?
    • @nlplearner 哦...你能告诉我你的新数据集的维度吗?
    【解决方案2】:

    使用dplyrpurrr 的解决方案。 imap_chr 可以通过每一行有效地应用一个函数。第一个参数是label#中的内容,第二个参数是行号。

    通常rowwise 操作在数据帧很大时会很慢,所以尽量避免rowwise 并尽可能使用替代方法。

    library(dplyr)
    library(purrr)
    
    dat2 <- dat %>%
      mutate(currentvalue = imap_chr(`label#`, ~dat[.y, .x]))
    dat2
    #   label1 label2 label3 label# currentvalue
    # 1 value1 value4 value7 label2       value4
    # 2 value2 value5 value8 label1       value2
    # 3 value3 value6 value9 label3       value9
    

    数据

    dat <- read.table(text = "label1 label2  label3  label
    value1  value4  value7  label2
    value2  value5  value8  label1
    value3  value6  value9  label3", header = TRUE) %>%
      setnames(c("label1", "label2", "label3", "label#"))
    

    【讨论】:

    • 感谢您抽出宝贵时间回复!当我从较大的数据中替换 df 和列名时,出现以下错误。你知道我该如何解决吗?错误:mutate()currentvalue 有问题。 ℹcurrentvalue = imap_chr(wordstim, ~responsebtwn[.y, .x])。 x 无法将元素 1 从列表强制转换为字符
    • @nlplearner responsebtwn 中的列名是否重复?
    • 不,它们采用您在上面看到的形式,但每个数字前面都有一个“标签”以外的词
    • @nlplearner 你的数据框中有列表列吗?
    • 我想是这样,但我不确定如何转换它们。我现在就去处理,谢谢!
    【解决方案3】:

    最简单的方法是在 rowwise 操作中使用 get 和 dplyr:

    library(dplyr)
    
    dat %>% rowwise() %>%
        mutate(curr_value = get(`label#`)) %>%
        ungroup()
    
    # A tibble: 3 × 5
      label1 label2 label3 `label#` curr_value
      <chr>  <chr>  <chr>  <chr>    <chr>     
    1 value1 value4 value7 label2   value4    
    2 value2 value5 value8 label1   value2    
    3 value3 value6 value9 label3   value9   
    

    【讨论】:

      猜你喜欢
      • 2019-06-05
      • 2021-10-21
      • 2020-03-22
      • 1970-01-01
      • 2016-02-14
      • 2019-06-06
      • 1970-01-01
      • 2020-09-19
      • 2018-08-08
      相关资源
      最近更新 更多