如何从一个函数中过滤的数据框中提取一列?



我试图包装一个函数,可以根据给定的参数从数据帧提取值:

> 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")

这个函数的作用是:

  1. 从任何您想要识别因子列的数据框架中,在我们的例子中是supp(由于整齐的计算编号"。

  2. 通过标识因子级别的因子列过滤数据帧。我知道你可能想要区分两个层次。但这很容易通过延长滤线来完成。在这个函数中,我们需要"

我们得到:

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")

这是因为您指示的是列(变量)的名称,所以您指示的是名称(字符串),因此它们必须在引号之间设置。

相关内容

  • 没有找到相关文章

最新更新