将特定行相加并将其作为新属性wtithout添加到匹配的行中,使用函数或R中的任何循环

时间:2017-10-21 00:55:21

标签: r dataframe vector

我的数据集示例如下:

df1 <- data.frame(v1 = c(1,1,1,4,5,5,4,1,2,3,5,6,2,1,5), 
               v2 = c(11,13,3,42,15,25,44,13,21,73,65,26,52,11,57))
 df2 <- data.frame(v3 = c(1,2,3,0,4,5,6,7))
 df2$newCol = 0

我想在不使用函数或任何循环的情况下执行以下伪代码(可以使用库函数)。因为数据集很长(50k行)并且处理公共代码需要很长时间。)

for i to length(df2$v3)
    for j to length(df1$v1)
       if (df2$v3[i] == df1$v1[j])
           df2$newCol[i] = df2$newCol[i] + df$v2[j]

2 个答案:

答案 0 :(得分:1)

df1 <- data.frame(v1 = c(1,1,1,4,5,5,4,1,2,3,5,6,2,1,5), 
                  v2 = c(11,13,3,42,15,25,44,13,21,73,65,26,52,11,57))
df2 <- data.frame(v3 = c(1,2,3,0,4,5,6,7))

您的代码

df2$newCol=0
for (i in 1 :length(df2$v3)){
  for (j in 1: length(df1$v1)){
     if (df2$v3[i] == df1$v1[j]){
      df2$newCol[i] = df2$newCol[i] + df1$v2[j]

      }

    }
}

我的解决方案

df1_ori=df1# keep it 
df1$sum=ave(df1$v2,df1$v1,FUN=sum)
df1=df1[!duplicated(df1$v1),]
df2$Newcol=df1$sum[match(df2$v3,df1$v1)]
df2[is.na(df2)]=0



df2
  v3 newCol Newcol
1  1     51     51
2  2     73     73
3  3     73     73
4  0      0      0
5  4     86     86
6  5    162    162
7  6     26     26
8  7      0      0

答案 1 :(得分:0)

我不确定它的效率如何,或者它是否适合您的使用案例,但使用dplyr可以实现的另一种方法是在df1中对每个唯一值进行求和v1中的值,然后将结果加入df2。在df2$v3中没有匹配值的df1$v1的任何值都设置为零:

library(dplyr)
df1 %>% group_by(v1) %>% 
  summarise(newCol = sum(v2)) %>%
  right_join(df2, by = c("v1" = "v3")) %>%
  rename(v3 = v1) %>%
  mutate(newCol = coalesce(newCol, 0))

#> # A tibble: 8 x 2
#>      v3 newCol
#>   <dbl>  <dbl>
#> 1     1     51
#> 2     2     73
#> 3     3     73
#> 4     0      0
#> 5     4     86
#> 6     5    162
#> 7     6     26
#> 8     7      0