在下文中,逻辑运算符似乎无法正常工作.
a = c(TRUE, FALSE, TRUE, FALSE, TRUE, TRUE)
b = c('a', 'b', 'c', 'de', 'f', 'g')
c = c(1, 2, 3, 4, 5, 6)
d = c(0, 0, 0, 0, 0, 1)
wtf = data.frame(a, b, c, d)
wtf$huh = apply(wtf, 1, function(row) {
if (row['a'] == T) { return('we win') }
if (row['c'] < 5) { return('hooray') }
if (row['d'] == 1) { return('a thing') }
return('huh?')
})
Run Code Online (Sandbox Code Playgroud)
生产:
> wtf
a b c d huh
1 TRUE a 1 0 hooray
2 FALSE b 2 0 hooray
3 TRUE c 3 0 hooray
4 FALSE de 4 0 hooray
5 TRUE f 5 0 huh?
6 TRUE g 6 1 a thing
Run Code Online (Sandbox Code Playgroud)
人们会想到在第1,3,5和6行中会出现这种情况we win.
有人可以向我解释(1)为什么会这样做,(2)如何解决这个问题,以免它发生,(3)为什么我的所有逻辑列似乎都被改为字符,(4)如何函数是否类型安全地应用于数据框中的行?
为什么会这样?因为是apply为矩阵而制作的.当你给它一个数据框时,发生的第一件事是它被转换为矩阵:
m = as.matrix(wtf)
m
# a b huh huh1
# [1,] " TRUE" "a" "huh?" "hooray"
# [2,] "FALSE" "b" "huh?" "huh?"
# [3,] " TRUE" "c" "huh?" "hooray"
# [4,] "FALSE" "de" "huh?" "huh?"
# [5,] " TRUE" "f" "huh?" "hooray"
# [6,] " TRUE" "g" "huh?" "hooray"
Run Code Online (Sandbox Code Playgroud)
当发生这种情况时,您的不同数据类型将丢失,并且您的数据框样式索引不再起作用:
m['a']
# [1] NA
Run Code Online (Sandbox Code Playgroud)
解?使用简单的for循环:
wtf$huh1 = NA
for (i in 1:nrow(wtf)) {
wtf$huh1[i] = if(wtf[i, 'a']) "hooray" else "huh?"
}
Run Code Online (Sandbox Code Playgroud)
如果你有一个功能foo那么
wtf$huh2 = NA
for (i in 1:nrow(wtf)) {
wtf$huh1[i] = foo(wtf[i, 'a'])
}
Run Code Online (Sandbox Code Playgroud)
可以对非矢量化的函数进行矢量化,以避免需要循环:
foov = Vectorize(foo)
# then you can
wtf$huh4 = foov(wtf$a)
Run Code Online (Sandbox Code Playgroud)