R:根据长度选择数据帧的单元格的快速方法

时间:2018-05-02 13:30:16

标签: r loops filter subset

我有一个大数据框,我想根据字符串的长度对数据帧进行子集化。

我有每个行的字符限制和优先顺序。

例如:

Column1   Column2                Column3             Column4
A1    Hotels in London, UK   Hotels in London        Hotels

如果len(column2)是< 30然后我想要第2列,否则如果len(column3)< 30然后我想要column3,否则我想要第4列。

即。我的偏好是第2列> column3>第4栏,但这些都受到30的字符限制。

目前,我有一个循环,需要

 for(i in 1:nrow(df) {
  if(nchar(df$`C2`[i]) <= 30) {
    df[i]$`selected` <- df`C2`[i]
  } else if(nchar(df$`C3`[i]) <= 30) {
    df$`selected`[i] <- df$`C3`[i]
  } else (nchar(df$`C4[i]) <= 30) {
     df$`selected`[i]<- df$`C4`[i]

2 个答案:

答案 0 :(得分:1)

这应该有效:

DF$Selected <- sapply(seq_len(nrow(DF)),
                      function(i) DF[i,which(nchar(DF[i,-1]) <= 30)[1] + 1] )

简要说明

对于每一行索引i,我们:

  • 选择行i的列值(不包括第一列),然后存储他们的nchar
    nchar(DF[i,-1])
  • 获取先前计算的&#34; nchars&#34;的第一个索引。这是<= 30
    which(nchar(DF[i,-1]) <= 30)[1]
  • 然后我们使用此索引选择列(我们需要为此索引添加+1,因为我们没有考虑第一列)
  • sapply *中的每个i使用1:nrow(DF)之前的操作,并将我们存储的向量返回到名为DF的{​​{1}}的新列中/ LI>

(*)

Select在逻辑上等同于seq_len(nrow(DF)),但更安全,因为如果1:nrow(DF)没有行,则会返回空向量,而DF将返回1:nrow(DF) (通常创造&#34;奇数&#34;结果)

答案 1 :(得分:1)

您可以使用case_when中的dplyr来对某个列进行条件选择。它是矢量化的,因此应该比循环更快。

library(dplyr)
df %>% mutate(selected = case_when(nchar(Column2)<30 ~ Column2,
                               nchar(Column2)>30 & nchar(Column3)<30 ~ Column3,
                               nchar(Column2)>30 & nchar(Column3)>30 ~ Column4
                               ))