如何使用dplyr扫描特定列?

如何使用dplyr扫描特定列?,r,dplyr,R,Dplyr,对于我的数据类型,一个非常常见的操作是对所有列应用归一化因子。使用扫描或缩放可以有效地完成此操作: normalized = scale(data, center = FALSE, scale = factors) # or normalized = sweep(data, 2, factors, `/`) 在哪里 然而,当我的数据前面有额外的列时,如何使用dplyr实现这一点?我可以在单独的语句中完成,但我希望在一个管道中完成。这是我的数据: data = structure(list(ID

对于我的数据类型,一个非常常见的操作是对所有列应用归一化因子。使用
扫描
缩放
可以有效地完成此操作:

normalized = scale(data, center = FALSE, scale = factors)
# or
normalized = sweep(data, 2, factors, `/`)
在哪里

然而,当我的数据前面有额外的列时,如何使用dplyr实现这一点?我可以在单独的语句中完成,但我希望在一个管道中完成。这是我的数据:

data = structure(list(ID = c(1, 2, 3, 4, 5, 6),
    Type = c("X", "X", "X", "Y", "Y", "Y"),
    A = c(3L, 174L, 6L, 1377L, 537L, 173L),
    B = c(1L, 128L, 2L, 1019L, 424L, 139L),
    C = c(3L, 66L, 2L, 250L, 129L, 40L),
    D = c(4L, 57L, 4L, 251L, 124L, 38L)),
    .Names = c("ID", "Type", "A", "B", "C", "D"),
    class = c("tbl_df", "data.frame"), row.names = c(NA, -6L))
我想在不涉及前两列的情况下对数据列进行变异。通常我可以用
每个
进行变异;但是,我如何无法将归一化因子传递给该函数:

data %>% mutate_each(funs(. / factors), A:D)

毫不奇怪,这假设我想用
因子来划分每一列,而不是用匹配因子来划分每一列。

在akrun的鼓励下,让我把我所做的作为一个答案发布在这里。我只是直觉地认为,您可能希望让R指示具有相同名称的列来执行此操作
mutate\u each
。例如,如果
指示列
A
,我认为另一个data.frame中名为
A
的列可能是
dplyr
可能喜欢的。因此,我为
因子
创建了一个数据框,然后分别使用
mutate\u
。看来结果是对的。由于我没有技术背景,恐怕我不能真正提供任何解释。我希望你不介意

factors <- data.frame(A = 1, B = 1.2, C = 0.8, D = 0.75)

mutate_at(data, vars(A:D), funs(. / foo$.))

# By the time I answered this question, the following was working.
# But mutate_each() is now deprecated.

# mutate_each(data, funs(. / factors$.), A:D)

#  ID Type    A           B      C          D
#1  1    X    3   0.8333333   3.75   5.333333
#2  2    X  174 106.6666667  82.50  76.000000
#3  3    X    6   1.6666667   2.50   5.333333
#4  4    Y 1377 849.1666667 312.50 334.666667
#5  5    Y  537 353.3333333 161.25 165.333333
#6  6    Y  173 115.8333333  50.00  50.666667

factors从
dplyr 1.0.0
中,您可以执行以下操作:

data %>%
 rowwise() %>%
 mutate(across(A:D)/factors)

     ID Type      A       B      C      D
  <dbl> <chr> <dbl>   <dbl>  <dbl>  <dbl>
1     1 X         3   0.833   3.75   5.33
2     2 X       174 107.     82.5   76   
3     3 X         6   1.67    2.5    5.33
4     4 Y      1377 849.    312.   335.  
5     5 Y       537 353.    161.   165.  
6     6 Y       173 116.     50     50.7 
数据%>%
行()
变异(跨越(A:D)/因子)
ID类型A B C D
1 X 30.833 3.75 5.33
2x174107。八十二点五七六
3 X 6 1.67 2.5 5.33
4年1377849。312335
55Y537353。161165
6 Y 173 116。50     50.7 

也许这有助于
数据%>%list(as.list(factors))%%>%减少(
/
,)
@akrun不,那根本不起作用。我做了以下实验。我为
因子创建了一个df,并尝试了
对每个因子进行变异。结果似乎不错。但是,我想这不是你想要的<代码>系数@akrun任务完成。:)另一种选择,虽然没有jazzuro的答案那么高效和简洁,但它是使用
do
data%>%do(data.frame([1:2],sweep([c(1:2)],2,factors,
/
这就是我想要的。然而,我发现它完全令人困惑和不直观。这是一个糟糕的API–与dplyr所期望的正好相反。@KonradRudolph我很高兴听到这是您所追求的。我理解你的沮丧。我最初做的是完全不同的事情。然后,我只想变得“愚蠢”一点,看看会发生什么。我想这表明API对很多用户来说并不一定是直观的。顺便说一下,我从你的问题中学到了一些新东西。非常感谢。@KonradRudolph这就是我使用
数据.table
-
setDT(data)[,name(factors):=Map(“/”,.SD,factors),.SDcols=names(factors)]
-不确定这是否会清除你的直觉栏。@jazzurro有没有办法用
mutate_at
做到这一点?我试着替换,但它不起作用。看起来
mutate\u每个
都将被弃用。@EricKrantz你必须学会如何使用这个函数。我更新了我的答案。看一看。是的,斑点很好。dplyr 1.0.0填补了其API中许多(尽管不是全部)突出的空白,几乎完全取代了基本data.frame功能。
# Experiment
foo <- list(A = 1, B = 1.2, C = 0.8, D = 0.75)

mutate_at(data, vars(A:D), funs(. / foo$.))

# mutate_each(data, funs(. / foo$.), A:D)

#  ID Type    A           B      C          D
#1  1    X    3   0.8333333   3.75   5.333333
#2  2    X  174 106.6666667  82.50  76.000000
#3  3    X    6   1.6666667   2.50   5.333333
#4  4    Y 1377 849.1666667 312.50 334.666667
#5  5    Y  537 353.3333333 161.25 165.333333
#6  6    Y  173 115.8333333  50.00  50.666667
data %>%
 rowwise() %>%
 mutate(across(A:D)/factors)

     ID Type      A       B      C      D
  <dbl> <chr> <dbl>   <dbl>  <dbl>  <dbl>
1     1 X         3   0.833   3.75   5.33
2     2 X       174 107.     82.5   76   
3     3 X         6   1.67    2.5    5.33
4     4 Y      1377 849.    312.   335.  
5     5 Y       537 353.    161.   165.  
6     6 Y       173 116.     50     50.7