Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
628 views
in Technique[技术] by (71.8m points)

r - Why does apply convert logicals in data frames to strings of 5 characters?

Suppose I have a data frame:

mydf <- data.frame(colA = c(1,20), colB = c("a", "ab"), colC = c(T, F))

Now suppose I want to apply a function to each row on the data frame. This function uses the boolean value of column C. When using apply, every non-string is converted to a string of the maximum length present in the column:

> apply(mydf, 1, '[', 3)
[1] " TRUE" "FALSE"

The string " TRUE" is no longer interpretable as a logical.

> ifelse(apply(mydf, 1, '[', 3), 1, 2)
[1] NA  2

I could solve this with a gsub(" ", "", x), but I'd bet there is a better way. Why does apply have this behavior when it could just directly convert the logicals to strings? Is there an apply-like function which does not have the above behavior?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you called apply, your data frame was converted to a character matrix. The spaces appear because each element is converted to the width of the widest element in the column.

You can do it with a for loop-like sapply call

> ( s <- sapply(seq(nrow(mydf)), function(i) mydf[i, 3]) )
# [1]  TRUE FALSE
> class(s)
# [1] "logical"

A workaround to what you are doing with apply would be

> as.logical(gsub("\s+", "", apply(mydf, 1, `[`, 3)))
# [1]  TRUE FALSE

But note that these are both exactly the same as

> mydf[,3]
# [1]  TRUE FALSE

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...