我有一些代码可以根据客户端名称从数据库中提取和处理数据。某些客户端可能具有不包含特定列名的数据,例如last_name
或first_name
。对于不使用last_name
或first_name
的客户,我不在乎。对于使用使用这两个字段之一的客户,我需要使用mutate()
toupper()
将这些列if()
使用,以便稍后在ETL过程中加入这些标准化字段。>
现在,我正在使用一系列library(dplyr)
set.seed(256)
b <- data.frame(id = sample(1:100, 5, FALSE),
col_name = sample(1000:9999, 5, FALSE),
another_col = sample(1000:9999, 5, FALSE))
d <- data.frame(id = sample(1:100, 5, FALSE),
col_name = sample(1000:9999, 5, FALSE),
last_name = sample(letters, 5, FALSE))
mutate_first_last <- function(df){
mutate_first_name <- function(df){
df %>%
mutate(first_name = first_name %>% toupper())
}
mutate_last_name <- function(df){
df %>%
mutate(last_name = last_name %>% toupper())
}
n <- c("first_name", "last_name") %in% names(df)
if (n[1] & n[2]) return(df %>% mutate_first_name() %>% mutate_last_name())
if (n[1] & !n[2]) return(df %>% mutate_first_name())
if (!n[1] & n[2]) return(df %>% mutate_last_name())
if (!n[1] & !n[2]) return(df)
}
语句和一些辅助函数来查找数据框的名称,然后对它们的名称进行更改(如果存在)。 I'm using if()
statements because ifelse()
is mostly vectorized and doesn't handle dataframes well.
> b %>% mutate_first_last()
id col_name another_col
1 48 8318 6207
2 39 7155 7170
3 16 4486 4321
4 55 2521 8024
5 15 1412 4875
> d %>% mutate_first_last()
id col_name last_name
1 64 7438 A
2 43 4551 Q
3 48 7401 K
4 78 3682 Z
5 87 2554 J
我能达到我期望的方式
if()
但这是处理此类任务的最佳方法吗?动态查看是否在数据框中存在列名,然后将其更改(如果存在)?在此函数中必须具有多个$.each($(".product-comment"), function (key, value) {
var showmoreHtml = $(this).html();
var showlessHtml = showmoreHtml.substr(0, 400);
if (showmoreHtml.length > 400) {
$(this).html(showlessHtml).append("<a href='' class='product-comment-more'> (...Show More)</a>");
}
$(this).on("click", ".product-comment-more", function (event) {
event.preventDefault();
$(this).parent(".product-comment").html(showmoreHtml).append("<a href='' class='product-comment-less'> (Show less)</a>");
});
$.ajax({
method: 'POST',
url: urlCreateReview,
data: form_data,
cache: false,
processData: false,
contentType: false,
success: function(data) {
$(".tab-comment-holder").load(" .tab-comment-holder");
},
语句似乎很奇怪。 是否有更简化的方式来处理这些数据?
答案 0 :(得分:4)
您可以将mutate_at
中的one_of
与dplyr
一起使用。仅当它与c("first_name", "last_name")
之一匹配时,此列才会突变。如果不匹配,它将生成一个简单的警告,但是您可以忽略或禁止它。
library(dplyr)
d %>%
mutate_at(vars(one_of(c("first_name", "last_name")), toupper)
id col_name last_name
1 19 7461 V
2 52 9651 H
3 56 1901 P
4 13 7866 Z
5 25 9527 U
# example with no match
b %>%
mutate_at(vars(one_of(c("first_name", "last_name"))), toupper)
id col_name another_col
1 34 9315 8686
2 26 5598 4124
3 17 3318 2182
4 32 1418 4369
5 49 4759 6680
Warning message:
Unknown variables: `first_name`, `last_name`
在?select_helpers
中还有一堆其他dplyr
-
这些函数使您可以根据变量的名称选择变量。
starts_with():以前缀开头
ends_with():以前缀结尾
contains():包含文字字符串
matches():匹配正则表达式
num_range():一个数字范围,例如x01,x02,x03。
one_of():字符向量中的变量。
everything():所有变量。
答案 1 :(得分:1)
在 dplyr 1.0
中,_at
或 _all
等 mutate 的作用域变体被 across()
替换。
此外,对于这种情况,最好的 tidy_select 助手是 any_of
,因为它将对存在的变量执行,但忽略那些不存在的变量(没有警告消息)。
因此,您可以编写以下内容:
# purrr syntax
d %>% mutate(across(any_of(c("first_name", "last_name")), ~toupper(.x)))
# function name syntax
d %>% mutate(across(any_of(c("first_name", "last_name")), toupper))
两者都返回变异的列
id col_name last_name
1 19 4398 Q
2 72 1135 S
3 54 9767 V
4 60 4364 K
5 35 1564 X
同时
b %>% mutate(across(any_of(c("first_name", "last_name")), toupper))
忽略列并因此返回(没有警告消息):
id col_name another_col
1 42 7601 4482
2 22 1773 7072
3 47 2719 5884
4 1 9595 5945
5 81 8044 3927