用户定义函数来创建和求和R中的一个子集
我需要帮助定义一个函数,该函数在数据库中创建一个向量,其中对于每一行,函数查看该数据库中的另一列,在指定的数据库中搜索该值创建第二个数据库的一个子集,该数据库由所有匹配的行组成,并对该子集中的一个单独列进行求和,然后将该值返回到原始数据库中新列的相应行。用户定义函数来创建和求和R中的一个子集
换句话说,我有一个看起来是这样的一个数据帧:
ID <- c('a', 'b', 'c', 'd', 'e')
M <- 20:39
df <- data.frame(cbind(ID, M))
df$M <- as.numeric(df$M)
> df
ID M
1 a 1
2 b 2
3 c 3
4 d 4
5 e 5
6 a 6
7 b 7
8 c 8
9 d 9
10 e 10
11 a 11
12 b 12
13 c 13
14 d 14
15 e 15
16 a 16
17 b 17
18 c 18
19 d 19
20 e 20
> str(df)
'data.frame': 20 obs. of 2 variables:
$ ID: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5 1 2 3 4 5 ...
$ M : num 1 2 3 4 5 6 7 8 9 10 ...
我想创建一个新的数据帧,Z
,这样Z <- data.frame(cbind(X, Y))
其中:
X <- as.character(unique(df$ID))
> X
[1] "a" "b" "c" "d" "e"
Y
是所有a的总和,所有b的总和,所有c的总和等的向量...
因此,Y
sh乌尔德等于c(34, 38, 42, 46, 50)
和我最后的结果应该是:
> Z
X Y
1 a 34
2 b 38
3 c 42
4 d 46
5 e 50
> str(Z)
'data.frame': 5 obs. of 2 variables:
$ X: chr "a" "b" "c" "d" ...
$ Y: num 34 38 42 46 50
要做到这一点,我已经试过第一次打开X
到数据帧(是不是容易的工作作为一个数据表):
> Z <- data.frame(X)
> Z
X
1 a
2 b
3 c
4 d
5 e
> str(Z)
'data.frame': 5 obs. of 1 variable:
$ X: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
然后定义Y
作为Z$Y <- sum(df[df$ID == Z$X, 2])
,但我不明白的唯一值:
> Z
X Y
1 a 210
2 b 210
3 c 210
4 d 210
5 e 210
我也试着定义函数f1()
像这样:
f1 <- function(v, w, x, y, z){sum(v[v$w == x$y, z])}
但让我:
> f1(df, 'ID', Z, 'X', 'M')
[1] 0
我发现从这个论坛另一篇文章的功能,做类似的事情:
f1 <- function(df, cols, match_with, to_x = 50){
df[cols] <- lapply(df[cols], function(i)
ifelse(grepl(to_x, match_with, fixed = TRUE), 'MID',
i))
return(df)
}
这看起来对在match_with
列中的值“50”,并且将值“MID”返回到由cols
指定的列的那一行,提供两列在相同的指定数据中e df
。因此,我需要用to_x = 50
替代to_x = 50
,而不是查找固定值“50”,查找列Z$X
中的任何值,而不是返回固定值“MID”,返回值的总和df[df$ID == Z$X, df$M]
。我已经写了以下的变化尝试这些改变自己:
f1 <- function(df, cols, match_with, to_x = df[ , 1], x){
df[cols] <- lapply(df[cols], function(i)
ifelse(grepl(to_x, match_with, fixed = TRUE), sum(x),
i))
return(df)
}
但是,到目前为止,还没有我的变化已经产生了预期的效果。这个人给我:
> f1(Z, df, cols = c('Y'), match_with = df$ID, x = df$M)
X Y
1 a 210
2 b 210
3 c 210
4 d 210
5 e 210
Warning messages:
1: In grepl(to_x, match_with, fixed = TRUE) :
argument 'pattern' has length > 1 and only the first element will be used
2: In `[<-.data.frame`(`*tmp*`, cols, value = list(Y = c(210, 210, :
replacement element 1 has 20 rows to replace 5 rows
这似乎是总结的df$M
而不是子集,其中df$ID == Z$X
全部。在其他变体中,它在第二个数据框中引用列时似乎有问题。
我对R有点新,并且几乎没有编写用户定义函数的经验(正如你可能通过这个问题所说的那样)。任何帮助将非常感谢!
没关系你好,我想我明白了!
> f1 <- function(col1, col2, df2, to_add){
+ lapply(col1, function(i){
+ df2$x <- grepl(i, col2, fixed = TRUE)
+ df3 <- df2[df2$x == TRUE, to_add]
+ sum(df3, na.rm = TRUE)
+ })}
> Z$Y <- f1(Z$X, df$ID, df, c('M'))
> Z
X Y
1 a 34
2 b 38
3 c 42
4 d 46
5 e 50