【问题标题】:Multiply specific values in columns of a dataframe columnwise with a vector将数据框列中的特定值与向量相乘
【发布时间】:2015-07-05 01:06:28
【问题描述】:

我是一个非常偶然的 R 用户,这是我第一次在这里或在线其他任何地方询问有关 R 的问题,所以如果有任何不清楚的地方,我提前道歉。

我有一个数字数据框,其中包含大约 100 列,每列都有相同的数字(在本例中为数字 10),需要乘以来自数字向量的值,该值特定于每一列。我完全被困住了,不胜感激。

这是一个简化的例子:

df

                    V1            V2          V3
1                   0             0           2  
2                   1             0           2  
3                   0             0           1  
4                   0             0           2  
5                   0             0           1  
6                  10             0           1  
7                   0             0           1  
8                   0             0           2  
9                   0            10           2  
10                  0             0           2  
11                 10             0           1  
12                  0             0          10  
13                  1             2           1  
14                  0             0           2  
15                  0             0           0  
16                  0             1           2  
17                  1             0          10  
18                  1             1           1  
19                  0             0           1  
20                  0             0           2  

对应的向量如下所示:

V

v1                 v2                 v3  
0.01256117         0.03037231         0.55444079  

因此,df 列 V1 的值“10”需要乘以向量 V 的值 v1,df 列 V2 的值“10”乘以向量 V 的值 v2,等等。

非常感谢任何帮助!

【问题讨论】:

  • 这听起来并不难,但您必须提供一段(更好的)代码(可重现的示例),以便用户帮助您。期望的输出将是一个加号。 Here 您可以了解如何制作可重现的示例。
  • 那么,您只想更改每列中的 10 位吗?
  • 完全正确,但要乘以特定于列的数字。

标签: r


【解决方案1】:

这是一种简单的方法:

# sample data
df<-data.frame(v1=c(1:10,10), v2= c(5:13,10,14), v3=8:18)
vec=c(0.1, 0.2, 0.3) # sample vector to multiply by
df
#   v1 v2 v3
#1   1  5  8
#2   2  6  9
#3   3  7 10
#4   4  8 11
#5   5  9 12
#6   6 10 13
#7   7 11 14
#8   8 12 15
#9   9 13 16
#10 10 10 17
#11 10 14 18

df2 <- t(t(df==10) * vec * t(df))
df[df==10] <- 0
df + df2
#   v1 v2 v3
#1   1  5  8
#2   2  6  9
#3   3  7  3
#4   4  8 11
#5   5  9 12
#6   6  2 13
#7   7 11 14
#8   8 12 15
#9   9 13 16
#10  1  2 17
#11  1 14 18

【讨论】:

  • 弗兰克,非常感谢,“简单的解决方案”对我来说很好用!你的回答为我节省了很多额外的时间......!
【解决方案2】:

这是一个变体

df1 <- (df!=10)*df + ((df==10)*df) * vec1[col(df)]
df1
#          V1        V2       V3
#1  0.0000000 0.0000000 2.000000
#2  1.0000000 0.0000000 2.000000
#3  0.0000000 0.0000000 1.000000
#4  0.0000000 0.0000000 2.000000
#5  0.0000000 0.0000000 1.000000
#6  0.1256117 0.0000000 1.000000
#7  0.0000000 0.0000000 1.000000
#8  0.0000000 0.0000000 2.000000
#9  0.0000000 0.3037231 2.000000
#10 0.0000000 0.0000000 2.000000
#11 0.1256117 0.0000000 1.000000
#12 0.0000000 0.0000000 5.544408
#13 1.0000000 2.0000000 1.000000
#14 0.0000000 0.0000000 2.000000
#15 0.0000000 0.0000000 0.000000
#16 0.0000000 1.0000000 2.000000
#17 1.0000000 0.0000000 5.544408
#18 1.0000000 1.0000000 1.000000
#19 0.0000000 0.0000000 1.000000
#20 0.0000000 0.0000000 2.000000

对于大数据集,使用lapply/Map等可能也更好

f1 <- function(x,y) {i <- x==10
                    x[i] <- x[i]*y 
                     x}
df2 <- data.frame(Map(f1, df, vec1))
df2 
#          V1        V2       V3
#1  0.0000000 0.0000000 2.000000
#2  1.0000000 0.0000000 2.000000
#3  0.0000000 0.0000000 1.000000
#4  0.0000000 0.0000000 2.000000
#5  0.0000000 0.0000000 1.000000
#6  0.1256117 0.0000000 1.000000
#7  0.0000000 0.0000000 1.000000
#8  0.0000000 0.0000000 2.000000
#9  0.0000000 0.3037231 2.000000
#10 0.0000000 0.0000000 2.000000
#11 0.1256117 0.0000000 1.000000
#12 0.0000000 0.0000000 5.544408
#13 1.0000000 2.0000000 1.000000
#14 0.0000000 0.0000000 2.000000
#15 0.0000000 0.0000000 0.000000
#16 0.0000000 1.0000000 2.000000
#17 1.0000000 0.0000000 5.544408
#18 1.0000000 1.0000000 1.000000
#19 0.0000000 0.0000000 1.000000
#20 0.0000000 0.0000000 2.000000

identical(df1, df2)
#[1] TRUE

或者data.table的选项

library(data.table)#v1.9.5+
setDT(df)
for(j in seq_along(df)){
 set(df, i=NULL, j=j, value= as.numeric(df[[j]]))
 set(df, i=which(df[[j]]==10), j=j, value= df[[j]][df[[j]]==10]*vec1[j])
}

df
#          V1        V2       V3
#1: 0.0000000 0.0000000 2.000000
#2: 1.0000000 0.0000000 2.000000
#3: 0.0000000 0.0000000 1.000000
#4: 0.0000000 0.0000000 2.000000
#5: 0.0000000 0.0000000 1.000000
#6: 0.1256117 0.0000000 1.000000
#7: 0.0000000 0.0000000 1.000000
#8: 0.0000000 0.0000000 2.000000
#9: 0.0000000 0.3037231 2.000000
#10:0.0000000 0.0000000 2.000000
#11:0.1256117 0.0000000 1.000000
#12:0.0000000 0.0000000 5.544408
#13:1.0000000 2.0000000 1.000000
#14:0.0000000 0.0000000 2.000000
#15:0.0000000 0.0000000 0.000000
#16:0.0000000 1.0000000 2.000000
#17:1.0000000 0.0000000 5.544408
#18:1.0000000 1.0000000 1.000000
#19:0.0000000 0.0000000 1.000000
#20:0.0000000 0.0000000 2.000000

数据

df <- structure(list(V1 = c(0L, 1L, 0L, 0L, 0L, 10L, 0L, 0L, 0L, 0L, 
10L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L), V2 = c(0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 10L, 0L, 0L, 0L, 2L, 0L, 0L, 1L, 0L, 1L, 
0L, 0L), V3 = c(2L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 10L, 
1L, 2L, 0L, 2L, 10L, 1L, 1L, 2L)), .Names = c("V1", "V2", "V3"
), class = "data.frame", row.names = c(NA, -20L))

vec1 <-  c(v1=0.01256117, v2 =0.03037231,v3  =0.55444079)

【讨论】:

    【解决方案3】:

    这是另一个建议:

    arr <- which(df==10, arr.ind=TRUE)
    df[arr] <- df[arr] * v[arr[,2]]
    #> df
    #          V1        V2       V3
    #1  0.0000000 0.0000000 2.000000
    #2  1.0000000 0.0000000 2.000000
    #3  0.0000000 0.0000000 1.000000
    #4  0.0000000 0.0000000 2.000000
    #5  0.0000000 0.0000000 1.000000
    #6  0.1256117 0.0000000 1.000000
    #7  0.0000000 0.0000000 1.000000
    #8  0.0000000 0.0000000 2.000000
    #9  0.0000000 0.3037231 2.000000
    #10 0.0000000 0.0000000 2.000000
    #11 0.1256117 0.0000000 1.000000
    #12 0.0000000 0.0000000 5.544408
    #13 1.0000000 2.0000000 1.000000
    #14 0.0000000 0.0000000 2.000000
    #15 0.0000000 0.0000000 0.000000
    #16 0.0000000 1.0000000 2.000000
    #17 1.0000000 0.0000000 5.544408
    #18 1.0000000 1.0000000 1.000000
    #19 0.0000000 0.0000000 1.000000
    #20 0.0000000 0.0000000 2.000000
    

    数据

    df <- structure(list(V1 = c(0L, 1L, 0L, 0L, 0L, 10L, 0L, 0L, 0L, 0L,10L, 
    0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L), V2 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,
    0L, 10L, 0L, 0L, 0L, 2L, 0L, 0L, 1L, 0L, 1L, 0L, 0L), 
    V3 = c(2L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 10L, 1L, 2L, 0L, 2L,
    10L, 1L, 1L, 2L)), .Names = c("V1", "V2", "V3"), class = "data.frame", 
    row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
    "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"))
    
    v <- c(0.01256117, 0.03037231, 0.55444079)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多