我想搜索一個變量的內容placement
,並根據所尋找的模式創建一個新變量term
。小例子...在R中,使用dplyr的mutate()創建一個新的變量,以另一個內容爲條件
首先我創建了一個搜索模式功能:
calcterm <- function(x){ # calcterm takes a column argument to read
print(x)
if (x %in% '_fa_') {
return ('fall')
} else if (x %in% '_wi_') {
return('winter')
} else if (x %in% '_sp_') {
return('spring')
} else {return('summer')
}
}
我將創建一個小的數據幀,我會再傳給dplyr的tbl_df
:
placement <- c('pn_ds_ms_fa_th_hrs','pn_ds_ms_wi_th_hrs' ,'pn_ds_ms_wi_th_hrs')
hours <- c(1230, NA, 34)
d <- data.frame(placement, hours)
library(dplyr)
d <- tbl_df(d)
>d
Source: local data frame [3 x 2]
placement hours
(fctr) (dbl)
1 pn_ds_ms_fa_th_hrs 1230
2 pn_ds_ms_wi_th_hrs NA
3 pn_ds_ms_wi_th_hrs 34
接下來,我用發生變異來實現我的功能:現在
表d的出現。目標是讀取placement
的內容,並創建一個新變量,該變量將根據placement
列中找到的模式生成值fall
,winter
,spring
或summer
。
d %>% mutate(term=calcterm(placement))
輸出給我留下了
[1] pn_ds_ms_fa_th_hrs pn_ds_ms_wi_th_hrs pn_ds_ms_wi_th_hrs
Levels: pn_ds_ms_fa_th_hrs pn_ds_ms_wi_th_hrs
Source: local data frame [3 x 3]
placement hours term
(fctr) (dbl) (chr)
1 pn_ds_ms_fa_th_hrs 1230 summer
2 pn_ds_ms_wi_th_hrs NA summer
3 pn_ds_ms_wi_th_hrs 34 summer
Warning messages:
1: In if (x %in% "_fa_") { :
the condition has length > 1 and only the first element will be used
2: In if (x %in% "_wi_") { :
the condition has length > 1 and only the first element will be used
3: In if (x %in% "_sp_") { :
the condition has length > 1 and only the first element will be used
因此,很明顯,我寫的東西錯在一開始...也許%in%
可以交換爲grep的格局?我不知道如何解決這個問題。
謝謝。
UPDATE
基於下面的反應,我更新這個跟我完全管系列中展示我如何實現這一點。我正在使用的數據是「廣泛的」,我首先翻轉它的軸,並從這些名稱中提取有用的信息。這個例子的工作---但在我自己的數據,當我到了發生變異()步,我得到的消息:Error: invalid subscript type 'list'
值得注意的是,後總結()我得到警告:
Warning message:
attributes are not identical across measure variables; they will be dropped
也許這與下一步失敗有關?由於警告沒有出現在我的例子中?
set.seed(1)
dfmaker <- function() {
setNames(
data.frame(
replicate(5, sample(c(NA, 300:500), 4, TRUE), FALSE)),
c('pn_ds_ms_fa_th_hrs','rn_ds_ms_wi_th_stu' ,'adn_ds_ms_wi_th_hrs','pn_ds_ms_wi_th_hrs' ,'rn_bsn_ds_ms_wi_th_hrs'))
}
d <- dfmaker()
library(dplyr)
d <- tbl_df(d)
grepl_vec_pattern = Vectorize(grepl, 'pattern')
calcterm = function(s) {
require(pryr)
s = as.character(s)
grepped_patterns = grepl_vec_pattern(s, pattern = c('_sp', '_su', '_fa', '_wi'))
stopifnot(any(rowSums(grepped_patterns) == 1)) # Ensure that there is exactly one match
reduce_to_colname_with_true = apply(grepped_patterns, 1, compose(names, which))
lut_table = c('_sp' = 'spring', '_su' = 'summer', '_fa' = 'fall', '_wi' = 'winter')
lut_table[reduce_to_colname_with_true]
}
select(d, matches("^pn_|^adn_|^bsn_"), -starts_with("rn_bsn")) %>% # all the pn, adn, bsn programs, for all information
select(contains("_hrs")) %>% # takes out just the hours
gather(placement, hours) %>% # flip it!
group_by(placement) %>% # gather all the schools into a single observation (replicated placement values at this point)
summarise(sumHours = sum(hours, na.rm=T)) %>%
mutate(term = calcterm(placement))
'%in%'是爲了與regex完全匹配。而'mutate'沒有做任何特殊的事情,這在基本R中是無法做到的,所以在這個操作中完全不需要'dplyr'。 –
你也可以在Excel中完成所有這些操作,這並不意味着你不應該使用R. OP會問'dplyr'中的問題,回答問題或者不回答問題。這對'dplyr'完全有效。 –
@PaulHiemstra這個問題的標題是「*按順序使用dplyr的mutate()...等等*」,而不是「*如何找到匹配......」等。我想說的是,爲了解決這個問題,你不應該關注如何使用'dplyr :: mutate'(具體的工具),因爲沒有什麼特別之處,而應該試着把重點放在問題上本身。 –