根据列名称将函数传递给多个列

时间:2015-09-21 15:26:32

标签: r dplyr

我有一个数据框(DF),其中3列有值,200列只有标题和NA值。作为一个例子:

  Row Price  Qty   2.10  2.15  2.20  2.25  ....
    1  2.10  100      0     0     0     0
    2  2.15  200      0     0     0     0   
    3  2.25  100      0     0     0     0    
    4  2.10  100      0     0     0     0  
    5  2.25  300      0     0     0     0  

我正在尝试使用dplyrmutate_each将函数传递给使用列标题名称的所有列4:n。该函数将改变每一列,以便在Price = Column Name的行中,然后应用Qty金额。见下文所需的结果:

  Row Price  Qty   2.10  2.15  2.20  2.25  ....
    1  2.10  100    100     0     0     0
    2  2.15  200      0   200     0     0   
    3  2.25  100      0     0     0   100    
    4  2.10  100    100     0     0     0  
    5  2.25  300      0     0     0   300  

有关如何执行此操作的任何想法?

# input data
DF <- structure(list(Row = 1:5, Price = c(2.1, 2.15, 2.25, 2.1, 2.25
), Qty = c(100L, 200L, 100L, 100L, 300L), X2.10 = c(0L, 0L, 0L, 
0L, 0L), X2.15 = c(0L, 0L, 0L, 0L, 0L), X2.20 = c(0L, 0L, 0L, 
0L, 0L), X2.25 = c(0L, 0L, 0L, 0L, 0L)), .Names = c("Row", "Price", 
"Qty", "2.10", "2.15", "2.20", "2.25"), class = "data.frame", row.names = c(NA, 
-5L))   

2 个答案:

答案 0 :(得分:6)

您可以通过重塑来创建价格列:

library(reshape2)
dcast(DF[1:3], Row+Price+Qty ~ Price, value.var = "Qty", fill = 0) 

#   Row Price Qty 2.1 2.15 2.25
# 1   1  2.10 100 100    0    0
# 2   2  2.15 200   0  200    0
# 3   3  2.25 100   0    0  100
# 4   4  2.10 100 100    0    0
# 5   5  2.25 300   0    0  300

在第二列中显示的价格不会使用上述方法获得自己的列。如果边缘情况很重要,我会使用data.table:

library(data.table)
setDT(DF)
for (j in names(DF)[-(1:3)]){  
  ii = which( DF$Price == as.numeric(j) )
  set(DF, i=ii, j=j, v=DF$Qty[ii]) }

#   Row Price Qty 2.10 2.15 2.20 2.25
# 1   1  2.10 100  100    0    0    0
# 2   2  2.15 200    0  200    0    0
# 3   3  2.25 100    0    0    0  100
# 4   4  2.10 100  100    0    0    0
# 5   5  2.25 300    0    0    0  300

我确定mutate_each可以做类似的事情。

答案 1 :(得分:1)

另一种方法是按如下方式进行连接:

[!] Breakpoint hit at Line 20 in somefile.inc: Some debug output here

联接可以与 data.table 的语法结合使用聚合和更新(就像子集一样)。我们的想法是使用require(data.table) # v1.9.6+ setDT(DF) for (p in tail(names(DF), -3L)) DF[.(Price=as.numeric(p)), (p) := Qty, on="Price"] DF[] # Row Price Qty 2.10 2.15 2.20 2.25 # 1: 1 2.10 100 100 0 0 0 # 2: 2 2.15 200 0 200 0 0 # 3: 3 2.25 100 0 0 0 100 # 4: 4 2.10 100 100 0 0 0 # 5: 5 2.25 300 0 0 0 300 参数提取匹配的行,并使用相应的值i更新该列的行。

请注意,这里没有制作副本。原始的 data.table 通过引用进行更新。