我试图包装一个函数,可以根据给定的参数从数据帧提取值:
> f <- function(df, factor, level1, level2, response) {
+ df1 <- df[df$factor == level1, ]$response
+ df2 <- df[df$factor == level2, ]$response
+ print(df1)
+ print(df2)
+ }
> f(ToothGrowth, supp, "VC", "OJ", len)
NULL
NULL
在上面的例子中,数据帧是ToothGrowth
,函数f
试图打印两个分开的数据帧:df1
包含supp
列等于"VC"
的行中的值的数组;和";OJ"fordf2
.
使用pandas的等效python代码如下(非常简单且工作良好):
def f(df: pd.DataFrame, factor: str, level1: str, level2: str, response: str):
p1 = df[df[factor] == level1][response]
p2 = df[df[factor] == level2][response]
print(p1, p2)
为什么这些输出只是R中的NULL
?实现这一目标的最佳实践是什么?
我是R的新手,但知道tidyverse
。然而,这对我来说似乎很奇怪,我真的不知道是否值得使用这样一个沉重的库来达到这个目的。
我很确定您需要这样的东西:
f <- function(df, factor, level, response) {
df <- df %>%
dplyr::filter({{factor}}==level) %>%
pull({{response}})
print(df)
}
f(ToothGrowth, supp, "VC", len)
#gives:
[1] 4.2 11.5 7.3 5.8 6.4 10.0 11.2 11.2 5.2 7.0 16.5 16.5 15.2 17.3 22.5
[16] 17.3 13.6 14.5 18.8 15.5 23.6 18.5 33.9 25.5 26.4 32.5 26.7 21.5 23.3 29.5
你的函数和函数调用产生了什么
f(ToothGrowth, "supp", "VC", "OJ", "len")
is:
[1] 4.2 11.5 7.3 5.8 6.4 10.0 11.2 11.2 5.2 7.0 16.5 16.5 15.2 17.3 22.5
[16] 17.3 13.6 14.5 18.8 15.5 23.6 18.5 33.9 25.5 26.4 32.5 26.7 21.5 23.3 29.5
[1] 15.2 21.5 17.6 9.7 14.5 10.0 8.2 9.4 16.5 9.7 19.7 23.3 23.6 26.4 20.0
[16] 25.2 25.8 21.2 14.5 27.3 25.5 26.4 22.4 24.5 24.8 30.9 26.4 27.3 29.4 23.0
如果这是你的目标(我不认为),那么你可以这样做:
ToothGrowth$len
给出:
[1] 4.2 11.5 7.3 5.8 6.4 10.0 11.2 11.2 5.2 7.0 16.5 16.5 15.2 17.3 22.5
[16] 17.3 13.6 14.5 18.8 15.5 23.6 18.5 33.9 25.5 26.4 32.5 26.7 21.5 23.3 29.5
[31] 15.2 21.5 17.6 9.7 14.5 10.0 8.2 9.4 16.5 9.7 19.7 23.3 23.6 26.4 20.0
[46] 25.2 25.8 21.2 14.5 27.3 25.5 26.4 22.4 24.5 24.8 30.9 26.4 27.3 29.4 23.0
对我来说更有意义的是你可能需要这样的东西:
f <- function(df, factor, level) {
df <- df %>%
dplyr::filter({{factor}}==level)
print(df)
}
f(ToothGrowth, supp, "VC")
这个函数的作用是:
从任何您想要识别因子列的数据框架中,在我们的例子中是
supp
(由于整齐的计算编号"。通过标识因子级别的因子列过滤数据帧。我知道你可能想要区分两个层次。但这很容易通过延长滤线来完成。在这个函数中,我们需要"
我们得到:
len supp dose
1 4.2 VC 0.5
2 11.5 VC 0.5
3 7.3 VC 0.5
4 5.8 VC 0.5
5 6.4 VC 0.5
6 10.0 VC 0.5
7 11.2 VC 0.5
8 11.2 VC 0.5
9 5.2 VC 0.5
10 7.0 VC 0.5
11 16.5 VC 1.0
12 16.5 VC 1.0
13 15.2 VC 1.0
14 17.3 VC 1.0
15 22.5 VC 1.0
16 17.3 VC 1.0
17 13.6 VC 1.0
18 14.5 VC 1.0
19 18.8 VC 1.0
20 15.5 VC 1.0
21 23.6 VC 2.0
22 18.5 VC 2.0
23 33.9 VC 2.0
24 25.5 VC 2.0
25 26.4 VC 2.0
26 32.5 VC 2.0
27 26.7 VC 2.0
28 21.5 VC 2.0
29 23.3 VC 2.0
30 29.5 VC 2.0
这是可扩展的,如我的答案开头所示:例如,如果我们想要得到向量:
在对参数添加响应后,只需将pull(response)
添加到函数中…
R和Python有相同点和不同点。你在R中的函数应该这样写:
f <- function(df, factor, level1, level2, response) {
df1 <- df[df[,factor] == level1, ][,response]
df2 <- df[df[,factor] == level2, ][,response]
print(df1)
print(df2)
}
当你写df$factor
时,你是在说有一个名为"factor"而不是传递(对象)factor
的值作为列的名称。
并且,正如@rawr所说,你必须引用召唤:
f(ToothGrowth, "supp", "VC", "OJ", "len")
这是因为您指示的是列(变量)的名称,所以您指示的是名称(字符串),因此它们必须在引号之间设置。