R(数据表):在循环中调用不同的列

cld4siwp  于 2023-02-14  发布在  其他
关注(0)|答案(4)|浏览(219)

我尝试在循环中调用data.table的不同列,以获得每列的唯一值。
考虑下表中的简单数据。

> df <- data.table(var_a = rep(1:10, 2),
+                  var_b = 1:20)
> df
    var_a var_b
 1:     1     1
 2:     2     2
 3:     3     3
 4:     4     4
 5:     5     5
 6:     6     6
 7:     7     7
 8:     8     8
 9:     9     9
10:    10    10
11:     1    11
12:     2    12
13:     3    13
14:     4    14
15:     5    15
16:     6    16
17:     7    17
18:     8    18
19:     9    19
20:    10    20

当我在循环外调用特定列时,我的代码可以正常工作,

> unique(df$var_a)
 [1]  1  2  3  4  5  6  7  8  9 10
> unique(df[, var_a])
 [1]  1  2  3  4  5  6  7  8  9 10
> unique(df[, "var_a"])
    var_a
 1:     1
 2:     2
 3:     3
 4:     4
 5:     5
 6:     6
 7:     7
 8:     8
 9:     9
10:    10

但在遍历data.table的不同列的循环中执行此操作时就不会出现这种情况。

> for(v in c("var_a","var_b")){
+   print(v)
+   df$v
+   unique(df[, .v])
+   unique(df[, "v"])
+ }
[1] "var_a"
Error in `[.data.table`(df, , .v) : 
  j (the 2nd argument inside [...]) is a single symbol but column name '.v' is not found. Perhaps you intended DT[, ...v]. This difference to data.frame is deliberate and explained in FAQ 1.1.
> 
> unique(df[, ..var_a])
Error in `[.data.table`(df, , ..var_a) : 
  Variable 'var_a' is not found in calling scope. Looking in calling scope because you used the .. prefix.
yqyhoc1h

yqyhoc1h1#

对于第一个问题,当您 * 间接 * 引用列名时,您可以使用双点..v语法,或者在data.table::[构造中添加with=FALSE

for (v in c("var_a", "var_b")) {
  print(v)
  print(df$v)
  ### either one of these will work:
  print(unique(df[, ..v]))
  # print(unique(df[, v, with = FALSE]))
}
# [1] "var_a"
# NULL
#     var_a
#     <int>
#  1:     1
#  2:     2
#  3:     3
#  4:     4
#  5:     5
#  6:     6
#  7:     7
#  8:     8
#  9:     9
# 10:    10
# [1] "var_b"
# NULL
#     var_b
#     <int>
#  1:     1
#  2:     2
#  3:     3
#  4:     4
#  5:     5
#  6:     6
#  7:     7
#  8:     8
#  9:     9
# 10:    10
# 11:    11
# 12:    12
# 13:    13
# 14:    14
# 15:    15
# 16:    16
# 17:    17
# 18:    18
# 19:    19
# 20:    20
#     var_b

但这只是打印它而不做任何更改。如果您只想查看每列中的唯一值(而不更改底层框架),那么我可能会使用

lapply(df[,.(var_a, var_b)], unique)
# $var_a
#  [1]  1  2  3  4  5  6  7  8  9 10
# $var_b
#  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

使用lapply(无论是对整个df还是对列的子集)也比另一个建议使用apply(df, 2, unique)更可取,尽管在这种情况下它返回相同的结果。

7tofc5zh

7tofc5zh2#

使用.subset2按列的名称引用列:

for(v in c("var_a","var_b")) {
  print(unique(.subset2(df, v)))
}
nbnkbykc

nbnkbykc3#

在第一个错误的信息之后,这将是在循环中调用的正确方法:

for(v in c("var_a","var_b")){

    print(unique(df[, ..v]))

}
# won't print all the lines

至于第二个错误,你没有声明一个名为“var_a”的变量,看起来你想通过名字来选择。

# works as you have shown
unique(df[, "var_a"])

# works once the variable is declared
var_a <- "var_a"
unique(df[, ..var_a])
xurqigkl

xurqigkl4#

您可能还对data.table的env参数感兴趣(参见开发版本);下面是一个示例,但您也可以在循环中使用它。

v="var_a"
df[, v, env=list(v=v)]

输出:

[1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10

相关问题