r - hlookup - व्लूकुप इन एक्सेल इन हिंदी




आर में vlookup और भरने(एक्सेल में) कैसे करें? (6)

मेरे पास 105000 पंक्तियों और 30 कॉलम के बारे में एक डेटासेट है। मेरे पास एक स्पष्ट चर है कि मैं इसे किसी संख्या में असाइन करना चाहता हूं। एक्सेल में, मैं शायद VLOOKUP साथ कुछ करूँगा और भरें।

मैं R में एक ही चीज़ करने के बारे में कैसे R ?

अनिवार्य रूप से, मेरे पास HouseType वैरिएबल है, और मुझे HouseTypeNo गणना करने की आवश्यकता है। यहां कुछ नमूना डेटा दिए गए हैं:

HouseType HouseTypeNo
Semi            1
Single          2
Row             3
Single          2
Apartment       4
Apartment       4
Row             3

@ बेन के उत्तर का समाधान # 2 अन्य सामान्य उदाहरणों में पुन: उत्पन्न नहीं होता है। उदाहरण में सही लुकअप देना होता है क्योंकि houses में अद्वितीय HouseType बढ़ते क्रम में दिखाई देता है। इसे इस्तेमाल करे:

hous <- read.table(header = TRUE,   stringsAsFactors = FALSE,   text="HouseType HouseTypeNo
  Semi            1
  ECIIsHome       17
  Single          2
  Row             3
  Single          2
  Apartment       4
  Apartment       4
  Row             3")

largetable <- data.frame(HouseType = as.character(sample(unique(hous$HouseType), 1000, replace = TRUE)), stringsAsFactors = FALSE)
lookup <- unique(hous)

बेंस समाधान # 2 देता है

housenames <- as.numeric(1:length(unique(hous$HouseType)))
names(housenames) <- unique(hous$HouseType)
base2 <- data.frame(HouseType = largetable$HouseType,
                    HouseTypeNo = (housenames[largetable$HouseType]))

जो कब

unique(base2$HouseTypeNo[ base2$HouseType=="ECIIsHome" ])
[1] 2

जब लुकअप टेबल से सही उत्तर 17 होता है

ऐसा करने का सही तरीका है

 hous <- read.table(header = TRUE,   stringsAsFactors = FALSE,   text="HouseType HouseTypeNo
      Semi            1
      ECIIsHome       17
      Single          2
      Row             3
      Single          2
      Apartment       4
      Apartment       4
      Row             3")

largetable <- data.frame(HouseType = as.character(sample(unique(hous$HouseType), 1000, replace = TRUE)), stringsAsFactors = FALSE)

housenames <- tapply(hous$HouseTypeNo, hous$HouseType, unique)
base2 <- data.frame(HouseType = largetable$HouseType,
  HouseTypeNo = (housenames[largetable$HouseType]))

अब लुकअप सही तरीके से किया जाता है

unique(base2$HouseTypeNo[ base2$HouseType=="ECIIsHome" ])
ECIIsHome 
       17

मैंने बेन्स के जवाब को संपादित करने की कोशिश की लेकिन मुझे उन कारणों से खारिज कर दिया गया जिन्हें मैं समझ नहीं पा रहा हूं।


आप plyr पैकेज से mapvalues() उपयोग कर सकते हैं।

प्रारंभिक आंकड़े:

dat <- data.frame(HouseType = c("Semi", "Single", "Row", "Single", "Apartment", "Apartment", "Row"))

> dat
  HouseType
1      Semi
2    Single
3       Row
4    Single
5 Apartment
6 Apartment
7       Row

लुकअप / क्रॉसवॉक टेबल:

lookup <- data.frame(type_text = c("Semi", "Single", "Row", "Apartment"), type_num = c(1, 2, 3, 4))
> lookup
  type_text type_num
1      Semi        1
2    Single        2
3       Row        3
4 Apartment        4

नया चर बनाएँ:

dat$house_type_num <- plyr::mapvalues(dat$HouseType, from = lookup$type_text, to = lookup$type_num)

या सरल प्रतिस्थापन के लिए आप एक लंबी लुकअप टेबल बना सकते हैं और इसे सीधे एक चरण में कर सकते हैं:

dat$house_type_num <- plyr::mapvalues(dat$HouseType,
                                      from = c("Semi", "Single", "Row", "Apartment"),
                                      to = c(1, 2, 3, 4))

परिणाम:

> dat
  HouseType house_type_num
1      Semi              1
2    Single              2
3       Row              3
4    Single              2
5 Apartment              4
6 Apartment              4
7       Row              3

पोस्टर ने exact=FALSE मूल्यों को देखने के बारे में नहीं पूछा था, लेकिन मैं इसे अपने संदर्भ और संभवतः अन्य लोगों के उत्तर के रूप में जोड़ रहा हूं।

यदि आप स्पष्ट मूल्यों को देख रहे हैं, तो अन्य उत्तरों का उपयोग करें।

एक्सेल का vlookup आपको 4 वें तर्क (1) match=TRUE साथ संख्यात्मक मानों के लिए लगभग मिलान करने की अनुमति देता है। मैं match=TRUE बारे में सोचता हूं match=TRUE एक थर्मामीटर पर मूल्यों की तरह match=TRUE । डिफ़ॉल्ट मान गलत है, जो स्पष्ट मानों के लिए बिल्कुल सही है।

यदि आप लगभग मिलान करना चाहते हैं (लुकअप करें), आर में फ़ंक्शन findInterval नामक एक फ़ंक्शन है, जिसे (जैसा कि नाम का तात्पर्य है) अंतराल / बिन मिलेगा जिसमें आपका निरंतर संख्यात्मक मान होगा।

हालांकि, मान लीजिए कि आप कई मूल्यों के लिए findInterval चाहते हैं। आप एक लूप लिख सकते हैं या एक लागू फ़ंक्शन का उपयोग कर सकते हैं। हालांकि, मुझे एक DIY वेक्टरकृत दृष्टिकोण लेने के लिए और अधिक कुशल पाया गया है।

मान लें कि आपके पास x और y द्वारा अनुक्रमित मानों का ग्रिड है:

grid <- list(x = c(-87.727, -87.723, -87.719, -87.715, -87.711), 
             y = c(41.836, 41.839, 41.843, 41.847, 41.851), 
             z = (matrix(data = c(-3.428, -3.722, -3.061, -2.554, -2.362, 
                                  -3.034, -3.925, -3.639, -3.357, -3.283, 
                                  -0.152, -1.688, -2.765, -3.084, -2.742, 
                                   1.973,  1.193, -0.354, -1.682, -1.803, 
                                   0.998,  2.863,  3.224,  1.541, -0.044), 
                         nrow = 5, ncol = 5)))

और आपके पास कुछ मान हैं जिन्हें आप एक्स और वाई द्वारा देखना चाहते हैं:

df <- data.frame(x = c(-87.723, -87.712, -87.726, -87.719, -87.722, -87.722), 
                 y = c(41.84, 41.842, 41.844, 41.849, 41.838, 41.842), 
                 id = c("a", "b", "c", "d", "e", "f")

यहां विज़ुअलाइज्ड उदाहरण दिया गया है:

contour(grid)
points(df$x, df$y, pch=df$id, col="blue", cex=1.2)

आप इस प्रकार के सूत्र के साथ एक्स अंतराल और वाई अंतराल पा सकते हैं:

xrng <- range(grid$x)
xbins <- length(grid$x) -1
yrng <- range(grid$y)
ybins <- length(grid$y) -1
df$ix <- trunc( (df$x - min(xrng)) / diff(xrng) * (xbins)) + 1
df$iy <- trunc( (df$y - min(yrng)) / diff(yrng) * (ybins)) + 1

आप इसे एक कदम आगे ले जा सकते हैं और इस तरह grid में जेड मानों पर एक (सरल) इंटरपोलेशन कर सकते हैं:

df$z <- with(df, (grid$z[cbind(ix, iy)] + 
                      grid$z[cbind(ix + 1, iy)] +
                      grid$z[cbind(ix, iy + 1)] + 
                      grid$z[cbind(ix + 1, iy + 1)]) / 4)

जो आपको ये मूल्य देता है:

contour(grid, xlim = range(c(grid$x, df$x)), ylim = range(c(grid$y, df$y)))
points(df$x, df$y, pch=df$id, col="blue", cex=1.2)
text(df$x + .001, df$y, lab=round(df$z, 2), col="blue", cex=1)

df
#         x      y id ix iy        z
# 1 -87.723 41.840  a  2  2 -3.00425
# 2 -87.712 41.842  b  4  2 -3.11650
# 3 -87.726 41.844  c  1  3  0.33150
# 4 -87.719 41.849  d  3  4  0.68225
# 6 -87.722 41.838  e  2  1 -3.58675
# 7 -87.722 41.842  f  2  2 -3.00425

ध्यान दें कि ix, और iy findInterval का उपयोग कर लूप के साथ भी पाया जा सकता है, उदाहरण के लिए दूसरी पंक्ति के लिए यहां एक उदाहरण है

findInterval(df$x[2], grid$x)
# 4
findInterval(df$y[2], grid$y)
# 2

जो df[2] में ix और iy मेल खाता है df[2]

फुटनोट: (1) vlookup के चौथे तर्क को पहले "मैच" कहा जाता था, लेकिन रिबन पेश करने के बाद इसका नाम बदलकर "[range_lookup]" कर दिया गया।


मुझे qdapTools::lookup या qdapTools::lookup बाइनरी ऑपरेटर %l% का उपयोग qdapTools::lookup पसंद है। यह एक्सेल vlookup के समान रूप से काम करता है, लेकिन यह स्तंभ संख्याओं के विरोध में नाम तर्क स्वीकार करता है

## Replicate Ben's data:
hous <- structure(list(HouseType = c("Semi", "Single", "Row", "Single", 
    "Apartment", "Apartment", "Row"), HouseTypeNo = c(1L, 2L, 3L, 
    2L, 4L, 4L, 3L)), .Names = c("HouseType", "HouseTypeNo"), 
    class = "data.frame", row.names = c(NA, -7L))


largetable <- data.frame(HouseType = as.character(sample(unique(hous$HouseType), 
    1000, replace = TRUE)), stringsAsFactors = FALSE)


## It's this simple:
library(qdapTools)
largetable[, 1] %l% hous

यदि मैं आपके प्रश्न को सही ढंग से समझता हूं, तो Excel के VLOOKUP के समतुल्य करने के लिए यहां चार विधियां हैं और R का उपयोग करके भरें:

# load sample data from Q
hous <- read.table(header = TRUE, 
                   stringsAsFactors = FALSE, 
text="HouseType HouseTypeNo
Semi            1
Single          2
Row             3
Single          2
Apartment       4
Apartment       4
Row             3")

# create a toy large table with a 'HouseType' column 
# but no 'HouseTypeNo' column (yet)
largetable <- data.frame(HouseType = as.character(sample(unique(hous$HouseType), 1000, replace = TRUE)), stringsAsFactors = FALSE)

# create a lookup table to get the numbers to fill
# the large table
lookup <- unique(hous)
  HouseType HouseTypeNo
1      Semi           1
2    Single           2
3       Row           3
5 Apartment           4

lookup टेबल में मानों का उपयोग करके HouseTypeNo में HouseTypeNo को भरने के लिए चार विधियां यहां दी गई हैं:

आधार में merge साथ पहले:

# 1. using base 
base1 <- (merge(lookup, largetable, by = 'HouseType'))

आधार में नामित वैक्टर के साथ एक दूसरी विधि:

# 2. using base and a named vector
housenames <- as.numeric(1:length(unique(hous$HouseType)))
names(housenames) <- unique(hous$HouseType)

base2 <- data.frame(HouseType = largetable$HouseType,
                    HouseTypeNo = (housenames[largetable$HouseType]))

तीसरा, plyr पैकेज का उपयोग कर:

# 3. using the plyr package
library(plyr)
plyr1 <- join(largetable, lookup, by = "HouseType")

चौथा, sqldf पैकेज का उपयोग कर

# 4. using the sqldf package
library(sqldf)
sqldf1 <- sqldf("SELECT largetable.HouseType, lookup.HouseTypeNo
FROM largetable
INNER JOIN lookup
ON largetable.HouseType = lookup.HouseType")

यदि यह संभव है कि लचीलेपन में कुछ घर के प्रकार lookup में मौजूद न हों तो बाएं शामिल होने का उपयोग किया जाएगा:

sqldf("select * from largetable left join lookup using (HouseType)")

अन्य समाधानों के अनुरूप परिवर्तनों की भी आवश्यकता होगी।

क्या आप यही करना चाहते हैं? मुझे बताएं कि आपको कौन सी विधि पसंद है और मैं टिप्पणी जोड़ूंगा।


merge का उपयोग एक्सेल में लुकअप से अलग है क्योंकि इसमें आपके डेटा को डुप्लिकेट (गुणा) करने की क्षमता है यदि प्राथमिक कुंजी बाधा लुकअप टेबल में लागू नहीं होती है या यदि आप all.x = T का उपयोग नहीं कर रहे हैं तो रिकॉर्ड्स की संख्या को कम करें।

यह सुनिश्चित करने के लिए कि आप उसमें परेशानी न करें और सुरक्षित रूप से देखें, मैं दो रणनीतियों का सुझाव देता हूं।

सबसे पहले लुकअप कुंजी में कई डुप्लिकेट पंक्तियों पर एक चेक बनाना है:

safeLookup <- function(data, lookup, by, select = setdiff(colnames(lookup), by)) {
  # Merges data to lookup making sure that the number of rows does not change.
  stopifnot(sum(duplicated(lookup[, by])) == 0)
  res <- merge(data, lookup[, c(by, select)], by = by, all.x = T)
  return (res)
}

यह आपको इसका उपयोग करने से पहले लुकअप डेटासेट को डी-डुप्लिकेट करने के लिए मजबूर करेगा:

baseSafe <- safeLookup(largetable, house.ids, by = "HouseType")
# Error: sum(duplicated(lookup[, by])) == 0 is not TRUE 

baseSafe<- safeLookup(largetable, unique(house.ids), by = "HouseType")
head(baseSafe)
# HouseType HouseTypeNo
# 1 Apartment           4
# 2 Apartment           4
# ...

दूसरा विकल्प लुकअप डेटासेट से पहला मिलान मूल्य लेकर Excel व्यवहार को पुन: उत्पन्न करना है:

firstLookup <- function(data, lookup, by, select = setdiff(colnames(lookup), by)) {
  # Merges data to lookup using first row per unique combination in by.
  unique.lookup <- lookup[!duplicated(lookup[, by]), ]
  res <- merge(data, unique.lookup[, c(by, select)], by = by, all.x = T)
  return (res)
}

baseFirst <- firstLookup(largetable, house.ids, by = "HouseType")

ये फ़ंक्शन lookup से थोड़ा अलग हैं क्योंकि वे एकाधिक कॉलम जोड़ते हैं।





vlookup