簡體   English   中英

將變量作為列名傳遞給dplyr?

[英]Pass variable as column name to dplyr?

我有一個非常難看的數據集,它是關系數據庫的平面文件。 這里是一個可重復性最小的例子:

df <- data.frame(col1 = c(letters[1:4],"c"), 
                  col1.p = 1:5, 
                  col2 = c("a","c","l","c","l"), 
                 col2.p = 6:10,
                  col3= letters[3:7],
                 col3.p = 11:20)

我需要能夠識別具有“c”的'col#'的'.p'值。 我之前關於SO的問題得到了第一部分: 在R中,找到每行包含字符串的列 我正在提供上下文。

tmp <- which(projectdata=='Transmission and Distribution of Electricity', arr.ind=TRUE)
cnt <- ave(tmp[,"row"], tmp[,"row"], FUN=seq_along)
maxnames <- paste0("max",sequence(max(cnt)))
projectdata[maxnames] <- NA
projectdata[maxnames][cbind(tmp[,"row"],cnt)] <- names(projectdata)[tmp[,"col"]]
rm(tmp, cnt, maxnames)

這會產生如下所示的數據框:

df
   col1 col1.p col2 col2.p col3 col3.p max1
1     a      1    a      6    c     11 col3
2     b      2    c      7    d     12 col2
3     c      3    l      8    e     13 col1
4     d      4    c      9    f     14 col2
5     c      5    l     10    g     15 col1
6     a      1    a      6    c     16 col3
7     b      2    c      7    d     17 col2
8     c      3    l      8    e     18 col1
9     d      4    c      9    f     19 col2
10    c      5    l     10    g     20 col1

當我試圖獲得與“max1”中的值匹配的“.p”時,我不斷收到錯誤。 我認為方法是:

df %>%
   mutate(my.p = eval(as.name(paste0(max1,'.p'))))
Error: object 'col3.p' not found

顯然,這不起作用,所以我想也許這類似於在函數中傳遞列名,我需要使用'get'。 這也行不通。

df %>%
   mutate(my.p = get(as.name(paste0(max1,'.p'))))
Error: invalid first argument
df %>%
   mutate(my.p = get(paste0(max1,'.p')))
Error: object 'col3.p' not found

我找到了一些可以擺脫這個錯誤的東西,使用來自不同但相關問題的data.table ,這里: httpdata.table 。 HTML 但是,它為每行提供了“col3.p”。 這是第一行的df$max1[1]df$max1[1]

library('dplyr')
library('data.table') # must have the data.table package
df %>%
  tbl_dt(df) %>% 
  mutate(my.p = get(paste0(max1,'.p')))

Source: local data table [10 x 8]

   col1 col1.p col2 col2.p col3 col3.p max1 my.p
1     a      1    a      6    c     11 col3   11
2     b      2    c      7    d     12 col2   12
3     c      3    l      8    e     13 col1   13
4     d      4    c      9    f     14 col2   14
5     c      5    l     10    g     15 col1   15
6     a      1    a      6    c     16 col3   16
7     b      2    c      7    d     17 col2   17
8     c      3    l      8    e     18 col1   18
9     d      4    c      9    f     19 col2   19
10    c      5    l     10    g     20 col1   20

使用lazyeval interp方法(從這個SO: ?熱到dplyr動態列名傳遞到自定義函數 )不會為我工作。 也許我正在錯誤地實施它?

library(lazyeval)
library(dplyr)
df %>%
  mutate_(my.p = interp(~colp, colp = as.name(paste0(max1,'.p'))))

我收到一個錯誤:

Error in paste0(max1, ".p") : object 'max1' not found

理想情況下,我都會有新列my.p等於相應p基礎上標識的列max1

我可以使用ifelse完成所有這些ifelse ,但我嘗試使用更少的代碼並使其適用於下一個丑陋的平面表。

我們可以使用data.table來做到這data.table 我們將'data.frame'轉換為'data.table'( setDT(df) ),按行序列分組, get paste輸出的值,並將( := )賦值給新列(' my.p')。

library(data.table)
setDT(df)[, my.p:= get(paste0(max1, '.p')), 1:nrow(df)]
df
#    col1 col1.p col2 col2.p col3 col3.p max1 my.p
# 1:    a      1    a      6    c     11 col3   11
# 2:    b      2    c      7    d     12 col2    7
# 3:    c      3    l      8    e     13 col1    3
# 4:    d      4    c      9    f     14 col2    9
# 5:    c      5    l     10    g     15 col1    5
# 6:    a      1    a      6    c     16 col3   16
# 7:    b      2    c      7    d     17 col2    7
# 8:    c      3    l      8    e     18 col1    3
# 9:    d      4    c      9    f     19 col2    9
#10:    c      5    l     10    g     20 col1    5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM