在Apply函数

时间:2018-12-17 17:31:49

标签: r apply

我有两个简单的数据帧A和B:

 A<-data.frame(V1=c(0.25,0.5,0.75,1),V2=c("a","b","c","d"))
 B<-data.frame(V2=c(1,2,3,4))
 rownames(B)=c(0.25,0.5,0.75,1)

现在我想根据B的行名称将B移到A的第三列。我尝试apply()

A$V3<-apply(A,1,function(x){return(B[rownames(B)==x[1],1])})

现在A看起来像这样:

    V1 V2 V3
1 0.25  a  1
2 0.50  b 
3 0.75  c  3
4 1.00  d   

仅当我再次运行相同的命令时,第三列中才会显示“ 2”和“ 4”:

    V1 V2 V3
1 0.25  a  1
2 0.50  b  2
3 0.75  c  3
4 1.00  d  4

如果我只运行一次,它似乎在第2行和第4行中返回numeric(0)。我尝试删除A中的V2列并仅运行一次命令。一切都好。没有价值缺失。

有人知道为什么第二行和第四行缺少值吗?

2 个答案:

答案 0 :(得分:1)

问题是,以这种方式使用apply时,您正在比较字符串而不是数字。

注意打印的内容

z = apply(A,1,function(x){
    print("Next")
    print(rownames(B))
    print(x[1])
    })

[1] "Next"
[1] "0.25" "0.5"  "0.75" "1"
    V1
"0.25"
[1] "Next"
[1] "0.25" "0.5"  "0.75" "1"
    V1
"0.50"
[1] "Next"
[1] "0.25" "0.5"  "0.75" "1"
    V1
"0.75"
[1] "Next"
[1] "0.25" "0.5"  "0.75" "1"
    V1
"1.00"

"0.5" == "0.50"
[1] FALSE

因此,您可能首先需要正确转换为numeric。这三个都可以使用:

A$V3 = apply(A,1,function(x){return(B[rownames(B)==as.numeric(x[1]),1])})
A$V3[match(rownames(B), A[,1])] = B[,1]
A$V3 = sapply(A[,1], function(x){return(B[rownames(B)==x[1],1])})

答案 1 :(得分:1)

这是一个需要dplyrtibble的解决方案。首先,我定义数据帧。

# Define data frames
A<-data.frame(V1=c(0.25,0.5,0.75,1),V2=c("a","b","c","d"))
B<-data.frame(V2=c(1,2,3,4))
rownames(B)=c(0.25,0.5,0.75,1)

接下来,我将B的行名转换为一列,将此列转换为数字,然后使用BAV1连接起来。

B %>% 
  rownames_to_column(var = "V1") %>% 
  mutate(V1 = as.numeric(V1)) %>% 
  right_join(A, by = "V1")

#     V1 V2.x V2.y
# 1 0.25    1    a
# 2 0.50    2    b
# 3 0.75    3    c
# 4 1.00    4    d